2
0
mirror of https://github.com/boostorg/bimap.git synced 2026-01-19 04:02:10 +00:00

first bimap commit

[SVN r37767]
This commit is contained in:
Matias Capeletto
2007-05-25 01:07:13 +00:00
commit b80ca94d5d
181 changed files with 29606 additions and 0 deletions

96
.gitattributes vendored Normal file
View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

75
doc/acknowledgements.qbk Executable file
View File

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

237
doc/bimap.hdf Executable file
View File

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

164
doc/bimap.qbk Executable file
View File

@@ -0,0 +1,164 @@
[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]]
[/ 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]]
[def __UNDER_CONSTRUCTION__ [$images/under_construction.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_TEST__ [@http://www.boost.org/libs/test/doc/index.html [*Boost.Test]]]
[/extern links]
[/ Extern Links ]
[def __CPP_STANDARD_LIBRARY_TECHNICAL_REPORT__ [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf C++ Standard Library Technical Report]]
[def __CPP_DEFECT_REPORT_130__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130 Defect Report 130]]
[def __TR1_ISSUES_LIST__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf Issues List]]
[def __BOOST_HASH_FUNCTION__ [@http://www.boost.org/regression-logs/cs-win32_metacomm/doc/html/hash.html boost::hash]]
[def __BOOST_PERMUTATION_ITERATOR__ [@http://www.boost.org/libs/iterator/doc/permutation_iterator.html `permutation_iterator`]]
[def __BOOST_ASSERT_MACRO__ [@where_it_is `BOOST_ASSERT`]]
[def __BOOST_MPL_FORWARD_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html MPL Forward Sequence]]
[def __BOOST_MPL_RANDOM_ACCESS_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/random-access-sequence.html MPL Random Access Sequence]]
[def __BOOST_MPL_EXTENSIBLE_SEQUENCE__ [@http://www.boost.org/libs/mpl/doc/refmanual/extensible-sequence.html MPL Extensible Sequence]]
[def __SGI_UNARY_FUNCTION__ [@http://www.sgi.com/tech/stl/UnaryFunction.html Unary Function]]
[def __SGI_BINARY_FUNCTION__ [@http://www.sgi.com/tech/stl/BinaryFunction.html Binary Function]]
[def __SGI_ASSIGNABLE__ [@http://www.sgi.com/tech/stl/Assignable.html Assignable]]
[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html Default Constructible]]
[def __SGI_BINARY_PREDICATE__ [@http://www.sgi.com/tech/stl/BinaryPredicate.html Binary Predicate]]
[def __SGI_CONTAINER__ [@http://www.sgi.com/tech/stl/Container.html Container]]
[def __SGI_SORTED_ASSOCIATIVE_CONTAINER__ [@http://www.sgi.com/tech/stl/SortedAssociativeContainer.html Sorted Associative Container]]
[def __SGI_UNIQUE_ASSOCIATIVE_CONTAINER__ [@http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html Unique Associative Container]]
[def __SGI_REVERSIBLE_CONTAINER__ [@http://www.sgi.com/tech/stl/ReversibleContainer.html Reversible Container]]
[def __SGI_RANDOM_ACCESS_CONTAINER__ [@http://www.sgi.com/tech/stl/RandomAccessContainer.html Random Access Container]]
[def __SGI_FRONT_INSERTION_SEQUENCE__ [@http://www.sgi.com/tech/stl/FrontInsertionSequence.html Front Insertion Sequence]]
[def __SGI_BACK_INSERTION_SEQUENCE__ [@http://www.sgi.com/tech/stl/BackInsertionSequence.html Back Insertion Sequence]]
[def __SGI_INPUT_ITERATOR__ [@http://www.sgi.com/tech/stl/InputIterator.html Input Iterator]]
[def __SGI_FORWARD_ITERATOR__ [@http://www.sgi.com/tech/stl/ForwardIterator.html Forward Iterator]]
[def __SGI_STRICT_WEAK_ORDERING__ [@http://www.sgi.com/tech/stl/StrictWeakOrdering.html Strict Weak Ordering]]
[def __EIFFEL__ [@http://www.eiffel.com/ Eiffel]]
[def __SAFE_STL__ [@http://www.horstmann.com/safestl.html Safe STL]]
[def __STL_PORT_DEBUG_MODE__ [@http://www.stlport.com/doc/debug_mode.html STLport Debug Mode]]
[def __CGAL__ [@http://www.cgal.org/ CGAL]]
[def __MYSQLPP__ [@http://tangentsoft.net/mysql++/ MySQL++]]
[def __STL_TREE_H__ [@http://www.sgi.com/tech/stl/stl_tree.h stl_tree.h]]
[def __ORDER_STATISTICS_TREE__ [@http://pine.cs.yale.edu/pinewiki/OrderStatisticsTree ['order-statistics trees]]]
[def __GENERIC_PROGRAMMING_MOVE_CONSTRUCTORS__ [@http://www.ddj.com/dept/cpp/184403855 "Generic<Programming>: Move Constructors]]
[def __CLARIFICATION_OF_INITIALIZATION__ [@http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html "Clarification of Initialization of Class Objects by rvalues"]]
[/ Code snippets ]
[import ../example/simple_bimap.cpp]
[import ../example/mighty_bimap.cpp]
[section Preface]
[heading Description]
Boost.Bimap is a bidirectional maps library for C++. With Boost.Bimap you can create associative containers in which both types can be used as key. A `bimap<X,Y>`
can be thought of as a combination of a `std::map<X,Y>` and a `std::map<Y,X>`.
The learning curve of bimap is almost flat if you know how to use standard
containers. A great deal of effort has been put into mapping the naming scheme of the
STL in Boost.Bimap. The library is designed to match the common STL containers.
[heading Influences and Related Work]
The design of Boost.Bimap interface follows the standard template library.
It has been strongly influenced by Joaquin Lopez Muñoz's Boost.MultiIndex library
(the heart of bimaps) and codeproject::bimap library.
[endsect]
[include introduction.qbk]
[include quick_tutorial.qbk]
[include tutorial.qbk]
[include bimap_and_boost.qbk]
[include reference.qbk]
[include compiler_specifics.qbk]
[include performance.qbk]
[include examples.qbk]
[include test_suite.qbk]
[include future_work.qbk]
[include release_notes.qbk]
[include rationale.qbk]
[include history.qbk]
[include acknowledgements.qbk]

385
doc/bimap_and_boost.qbk Executable file
View File

@@ -0,0 +1,385 @@
[/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.
]
[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_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 `<boost/bimap/support/lambda.hpp>`
to allow a sounder solution. The placeholders are named _key and _data and both
are equivalent to boost::lambda::_1. There are two reasons to include this placeholders:
the code looks better with them and they avoid the clash problem between lambda::_1 and
boost::_1 from Boost.Bind.
[import ../example/bimap_and_boost/lambda.cpp]
[@../../example/bimap_and_boost/lambda.cpp Go to source code]
[code_bimap_and_boost_lambda]
[endsect]
[section Boost.Range]
Boost.Range is a collection of concepts and utilities that are particularly useful
for specifying and implementing generic algorithms.
Generic algorithms have so far been specified in terms of two or more iterators.
Two iterators would together form a range of values that the algorithm could
work on. This leads to a very general interface, but also to a somewhat clumsy
use of the algorithms with redundant specification of container names. Therefore
we would like to raise the abstraction level for algorithms so they specify their
interface in terms of Ranges as much as possible.
As Boost.Bimap views are signature-compatible with their standard
container counterparts, they are compatible with the concept of a range.
As an additional feature, ordered bimap views offer a function named
`range` that allows a range of values to be obtained.
[import ../example/bimap_and_boost/range.cpp]
If we have some generic functions that accepts ranges:
[code_bimap_and_boost_range_functions]
We can use them with Boost.Bimap with the help of the `range` function.
[code_bimap_and_boost_range]
[@../../example/bimap_and_boost/range.cpp Go to source code]
[endsect]
[section Boost.Property_map]
The Boost Property Map Library consists mainly of interface specifications in the form of
concepts (similar to the iterator concepts in the STL). These interface specifications
are intended for use by implementers of generic libraries in communicating requirements on
template parameters to their users. In particular, the Boost Property Map concepts define a
general purpose interface for mapping key objects to corresponding value objects, thereby
hiding the details of how the mapping is implemented from algorithms.
The need for the property map interface came from the Boost Graph Library (BGL), which
contains many examples of algorithms that use the property map concepts to specify their
interface. For an example, note the ColorMap template parameter of the breadth_first_search.
In addition, the BGL contains many examples of concrete types that implement the property map
interface. The adjacency_list class implements property maps for accessing objects
(properties) that are attached to vertices and edges of the graph.
The counterparts of two of the views of Boost.Bimap map, the `set` and
`unordered_set`, are read-write property maps. In order to use these, you
need to include one of the following headers:
#include <boost/bimap/property_map/set_support.hpp>
#include <boost/bimap/property_map/unordered_set_support.hpp>
The following is adapted from the example in the Boost.PropertyMap
documentation.
[import ../example/bimap_and_boost/property_map.cpp]
[@../../example/bimap_and_boost/property_map.cpp Go to source code]
[code_bimap_and_boost_property_map]
[endsect]
[endsect]
[section Dependencies]
Boost.Bimap is built on top of several Boost libraries. The rationale
behind this decision is keeping the Boost code base small by reusing
existent code. The libraries used are well-established and have been
tested extensively, making this library easy to port since all the hard
work has already been done. The glue that holds everything together is
Boost.MPL. Clearly Boost.MultiIndex is the heart of this library.
[table Boost Libraries needed by Boost.Bimap
[[Name][Description][author]]
[[ __BOOST_MULTI_INDEX__ ][
Containers with multiple STL-compatible access interfaces]
[Joaquín M López Muñoz]]
[[ __BOOST_MPL__ ][
Template metaprogramming framework of compile-time algorithms, sequences and metafunction classes]
[Aleksey Gurtovoy]]
[[ __BOOST_TYPE_TRAITS__ ][
Templates for fundamental properties of types.]
[John Maddock, Steve Cleary]]
[[ __BOOST_ENABLE_IF__ ][
Selective inclusion of function template overloads]
[Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine]]
[[ __BOOST_ITERATORS__ ][
Iterator construction framework, adaptors, concepts, and more.]
[Dave Abrahams, Jeremy Siek, Thomas Witt]]
[[ __BOOST_CALL_TRAITS__ ][
Defines types for passing parameters.]
[John Maddock, Howard Hinnant]]
[[ __BOOST_STATIC_ASSERT__ ][
Static assertions (compile time assertions).]
[John Maddock]]
]
[table Optional Boost Libraries
[[Name][Description][author][Purpose]]
[[ __BOOST_SERIALIZATION__ ][
Serialization for persistence and marshalling]
[Robert Ramey]
[Serialization support for bimap containers and iterators]]
[[ __BOOST_ASSIGN__ ][
Filling containers with constant or generated data has never been easier]
[Thorsten Ottosen]
[Help to fill a bimap or views of it]]
[[ __BOOST_HASH__ ][
A TR1 hash function object that can be extended to hash user defined types]
[Daniel James]
[Default hashing function]]
[[ __BOOST_LAMBDA__ ][
Define small unnamed function objects at the actual call site, and more]
[from Jaakko Järvi, Gary Powell]
[Functors for modify, range, lower_bound and upper_bound]]
[[ __BOOST_RANGE__ ][
A new infrastructure for generic algorithms that builds on top of the new
iterator concepts]
[Thorsten Ottosen]
[Range based algorithms]]
[[ __BOOST_PROPERTY_MAP__ ][
Concepts defining interfaces which map key objects to value objects]
[Jeremy Siek]
[Integration with BGL]]
]
[table Additional Boost Libraries needed to run the test-suite
[[Name][Description][author]]
[[ __BOOST_TEST__ ][
Support for simple program testing, full unit testing, and for program execution monitoring.]
[Gennadiy Rozental]
]
]
[endsect]
[endsect]

54
doc/compiler_specifics.qbk Executable file
View File

@@ -0,0 +1,54 @@
[/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 ]]
[[VS 7.1 ][Windows ][Supported ]]
[[VS 8.0 ][Windows ][Supported ]]
[[ICC 7.1 ][Windows ][Not Supported ]]
[[ICC 8.0 ][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]

13
doc/directdoxygen.jam Normal file
View File

@@ -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" > "$(<)"
}

220
doc/examples.qbk Executable file
View File

@@ -0,0 +1,220 @@
[/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/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/serialization.cpp
serialization.cpp: ]]
[Bimap and Boost.Serialization: Load and save bimaps and iterators ]]
]
[table Boost.MultiIndex to Boost.Bimap path examples
[[Program ][Description ]]
[[[@../../example/mi_to_b_path/bidirectional_map.cpp
bidirectional_map.cpp ]]
[Boost.MultiIndex to Boost.Bimap path example ]]
[[[@../../example/mi_to_b_path/hashed_indices.cpp
hashed_indices.cpp ]]
[Boost.MultiIndex to Boost.Bimap path example ]]
[[[@../../example/mi_to_b_path/tagged_bidirectional_map.cpp
tagged_bidirectional_map.cpp ]]
[Boost.MultiIndex to Boost.Bimap path example ]]
]
[endsect]
[section Simple Bimap]
This is the example from the one minute tutorial section.
[@../../example/simple_bimap.cpp Go to source code]
[code_simple_bimap]
You can rewrite it using tags to gain readability.
[@../../example/tagged_simple_bimap.cpp Go to source code]
[import ../example/tagged_simple_bimap.cpp]
[code_tagged_simple_bimap]
[endsect]
[section Mighty Bimap]
This is the translator example from the tutorial.
In this example the collection type of relation is changed to allow the iteration
of the container.
[@../../example/mighty_bimap.cpp Go to source code]
[code_mighty_bimap]
[endsect]
[section MultiIndex to Bimap Path - Bidirectional Map]
This is example 4 in Boost.MultiIndex documentation.
[blurb
This example shows how to construct a bidirectional map with multi_index_container.
By a bidirectional map we mean a container of elements of
`std::pair<const FromType,const ToType>` such that no two elements exists with the
same first or second value (`std::map` only guarantees uniqueness of the first member).
Fast look-up is provided for both keys. The program features a tiny Spanish-English
dictionary with on-line query of words in both languages.
]
[heading Boost.MultiIndex]
[@../../example/mi_to_b_path/mi_bidirectional_map.cpp Go to source code]
[import ../example/mi_to_b_path/mi_bidirectional_map.cpp]
[code_mi_to_b_path_mi_bidirectional_map]
[heading Boost.Bimap]
[@../../example/mi_to_b_path/bidirectional_map.cpp Go to source code]
[import ../example/mi_to_b_path/bidirectional_map.cpp]
[code_mi_to_b_path_bidirectional_map]
Or better, using tags...
[@../../example/mi_to_b_path/tagged_bidirectional_map.cpp Go to source code]
[import ../example/mi_to_b_path/tagged_bidirectional_map.cpp]
[code_mi_to_b_path_tagged_bidirectional_map]
[endsect]
[section MultiIndex to Bimap Path - Hashed indices]
This is example 8 of Boost.MultiIndex.
[blurb
Hashed indices can be used as an alternative to ordered indices when fast look-up is needed and sorting
information is of no interest. The example features a word counter where duplicate entries are checked by
means of a hashed index.
]
[heading Boost.MultiIndex]
[@../../example/mi_to_b_path/mi_hashed_indices.cpp Go to source code]
[import ../example/mi_to_b_path/mi_hashed_indices.cpp]
[code_mi_to_b_path_mi_hashed_indices]
[heading Boost.Bimap]
[@../../example/mi_to_b_path/hashed_indices.cpp Go to source code]
[import ../example/mi_to_b_path/hashed_indices.cpp]
[code_mi_to_b_path_hashed_indices]
[endsect]
[endsect]

48
doc/future_work.qbk Executable file
View File

@@ -0,0 +1,48 @@
[/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.
[heading Hooking Data]
In general, programmers use maps to access information quickly.
Boost.Bimap will allow the user to hook data inside the bimap so it is not
necessary to maintain another map. This a possible code example:
typedef bimap< int, string, hook_data< string > > bm_type;
bm_type bm;
//...
bm.left_map.data(28928546) = "teacher";
bm.right_map.data("John Gray") = "singer";
bm_type::left_iterator iter = bm.left_map.find(23345647);
iter->data = "programmer";
bm_type::iterator iter = bm.find( bm_type::pair_by<member_at::left>(23345647,"Green Dert") );
iter->data = "student";
bm.insert( bm_type::value_type_by<member_at::left>(1456783342,"Fred Bypass","unemployed") );
[endsect]

450
doc/history.qbk Executable file
View File

@@ -0,0 +1,450 @@
[/license
Boost.Bimap
Copyright (c) 2006-2007 Matias Capeletto
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]
[/ QuickBook Document version 1.4 ]
[section History]
[section The long path from Code Project to Boost]
[variablelist
[[2002 - bimap at Code Project]
[
Joaquin Lopez Muñoz posted his first
[@http://www.codeproject.com/vcpp/stl/bimap.asp#test_suite bimap library]
in 2002. Tons of users have been using it. He then
[@http://aspn.activestate.com/ASPN/Mail/Message/boost/1404881 asked the
list for interest] in his library in 2003. Luckily, there was a lot of
interest and Joaquin started to boostify the code. At some point all the
developers seemed to agree that, rather than a bidirectional map, it would
be better to work on an N-indexed set that contained Joaquin's library as a
particular case.
]]
[[2003 - multiindex_set]
[
The library grew enormously and was ready for a formal review in
2003. At this point, the container was a lot more powerful, but
everything comes with a price and this new beast lacked the simplicity
of the original bimap.
]]
[[2004 - indexed_set]
[
In 2004, the formal review ended well for the new multi-indexed
container. This Swiss army knife introduced several new features, such
as non-unique indexes, hashed indices and sequenced indices. In the list
of improvements to the library, it was mentioned that a bidirectional
map should be coded in top of this container.
]]
[[2005 - multi_index_container]
[
Once in Boost, the library switched to the now familiar name
"Boost.MultiIndex". Late in 2004, it formally became a member of Boost.
Joaquin continued to enchance the library and added new features such as
composite keys and random-access indices.
]]
[[2006 - Multi Index Specialized Containers SoC project]
[
In 2006, during the formal review of Boost.Property_tree, the need
for a bidirectional map container built on top of Boost.MultiIndex arose
again. Boost entered the Google SoC 2006 as a mentor organization at the
same time. Joaquin put himself forward as a mentor. He proposed to build
not only a bidirectional map, but a myriad multi-indexed specialized
containers. Matias Capeletto presented an application to code Boost.Misc
for the SoC and was elected, along with nine other students. Matias's and
Joaquin's SoC project ends with a working implementation of the bimap
library that was presented in an informal review. By the end of the year
the library was queued for a formal review.
]]
[[2007 - Boost.Bimap]
[
The formal review took place at the beggining of the year and Boost.Bimap
was accepted in Boost.
]]
]
[endsect]
[section MultiIndex and Bimap]
This is the conversation thread that began during Boost.PropertyTree formal
review process. The review was very interesting and very deep topics were
addressed. It is quite interesting and it is now part of this library history.
Enjoy!
[*Marcin]
[:['
The biggest virtue of property_tree is easy to use interface.
If we try to make generic tree of it, it will be compromised.
]]
[*Gennadiy]
[:['
IMO the same result (as library presents) could be achieved
just by using multi_index.
]]
[*Marcin]
[:['
Could you elaborate more on that? I considered use of
multi_index to implement indexing for properties, but it only affected the
implementation part of library, not interface, and because I already had a
working, exception safe solution, I didn't see the reason to dump it and add
another dependency on another library.
]]
[*Gennadiy]
[:['
I mean why do I need this half baked property_tree as another
data structure? Property tree supports nothing in itself. It's just a data
structure. You have parsers that produce property tree out of different sources.
But you mat as well produce maps or something else. Here for example All that
I need to do to "implement" similar functionality as your property tree:
]]
``
// Data structure itself
template<typename ValueType,typename KeyType>
struct Node;
template<typename ValueType,typename KeyType>
struct ptree_gen {
typedef std::pair<KeyType,Node<ValueType,KeyType> > mi_value;
typedef multi_index_container<mi_value, indexed_by<...> > type;
};
template<typename ValueType,typename KeyType>
struct Node {
ValueType v;
ptree_gen<ValueType,KeyType>::type children;
};
// serialization support
template<class Archive,typename ValueType,typename KeyType>
void serialize(Archive & ar, Node<ValueType,KeyType>& n,
const unsigned int version)
{
ar & n.v;
ar & n.children;
}
// some access methods
template<typename ValueType,typename KeyType>
ValueType const&
get( string const& keys, ptree_gen<ValueType,KeyType>::type const& src )
{
std::pait<string,string> sk = split( keys, "." );
Node const& N = src.find( sk.first );
return sk.second.empty() ? N.v : get( sk.second, N.children );
}
``
[:['
Use it like this:
]]
``
ptree_gen<string,string>::type PT;
boost::archive::text_iarchive ia( std::ifstream ifs("filename") );
ia >> PT;
string value = get( "a.b.c.d", PT );
``
[:['
Now tell me how property_tree interface is easier? And what is the value in
50k of Code you need to implement this data structure.
]]
[*Thorsten]
[:['
Seriously Gennadiy, do you really see newbies writing
the code you just did?
]]
[*Marcin]
[:['
What you just implemented is stripped down, bare bones version
of property_tree that, among other things, does not allow you to produce human
editable XML files. Now add more interface (aka get functions), add more
archives to serialization lib, add customization, add transparent
translation from strings to arbitrary types and vice versa. Spend some weeks
trying to get all the corner cases right, and then some more weeks trying to
smooth rough edges in the interface. Then write tests. Write docs. At the
end, I believe you will not get much less code than there is in the library
already. Maybe you get some savings by using multi_index instead of manual
indexing.
]]
[:['
The reason why ptree does not use multi index is because implementation
existed long before I considered submitting to boost, probably before even I
knew of multi index existence. It was working well. Later, when I was
improving it during pre-review process, I seriously considered using
multi-index. But I decided it is not worth throwing everything out.
]]
[:['
Although ptree has large interface with many functions modifying state of
the tree, it uses "single point of change" approach. Every insert eventually
goes through one function, which takes care of exception safety and keeping
index in sync with data. The same applies to erase. This function has 9
lines of code in case of insert, and (by coincidence) also 9 in case of
erase. By using multi index these functions would obviously be simplified,
maybe to 4 lines each. Net gain: 10 lines of code (out of several hundred in
ptree_implementation.hpp).
]]
[:['
I'm aware that there are performance gains to be reaped as well, but at that
time I was rather focusing on getting the interface right.
]]
[*Dave]
[:['
That's perfectly reasonable, but (through no fault of yours)
it misses the point I was trying to make. I guess I should have said,
"...that demonstrates it to be the best implementation."
]]
[:['
All I'm saying is that the extent to which a Boost library
implementation should leverage other Boost libraries is not a question
that can always be decided based on following simple guidelines, and
that if this library is accepted, it's worth revisiting your decision.
]]
[*Thorsten]
[:['
I think it is important to focus on the interface in
the review, but I also see several benefits of an implementation that builds on
Boost.MultiIndex:'
]]
[:['- fewer bugs like the one Joaquin found]]
[:['- better space efficiency]]
[:['- exception-safety guarantees are immediately full-filled (I haven't
looked, but I suspect that there are several bugs in this area)]]
[*Daniel]
[:['
Multi_index supports everything a bimap would, but its
interface is more cumbersome. I for one won't use a W3DOM-like library
if we get one, but I would happily use property_tree. I've also only
used multi_index once, and that was to use it as a bidirectional map.
Property_tree covers other areas as well as being a potential subset of
an XML library, but I still hold there is value in such a subset.
]]
[*Boris]
[:['
I haven't used program_options yet. But if I understand
correctly both libraries seem to support storing and accessing data with
strings that might describe some kind of hierarchy. This seems to be the core
idea of both libraries - is this correct?
]]
[:['
Then it wouldn't matter much what container is used. However a generic tree
which can store data hierarchically probably makes most sense. If I
understand correctly both libraries could make use of such a class?
]]
[*Marcin]
[:['
I think generic tree container is material for another library.
Whether property_tree should be based on it or not is a matter of internal
implementation, and generally of little interest to users. The biggest value
of property_tree is in its easy to use interface, that should not be
compromised, if at all possible. I have been already reassured in this view
by quite many people who took their time to review the library.
]]
[*Boris]
[:['
I was trying to see the big picture: I rather prefer a C++
standard based on a few well-known concepts like containers, iterators,
algorithms etc. instead of having a C++ standard with hundreds of components
which are tailored for specific needs, collaborate with only a handful of other
components and think they provide an easy-to-use interface while all the
easy-to-use interfaces make the whole standard less easy-to-use.
]]
[:['
That said I have used your property tree library myself to read and write a
configuration file. It was indeed very easy to use. However it would have
been even easier if it was something I had known before like eg. an
iterator. For now I will definitely use your property tree library but would
appreciate if existing concepts were reused many C++ developers are familiar
with. My opinion is that your library should be a part of Boost but should
be more generalized in the future.
]]
[*Thorsten]
[:['
Well, I think we need both. Boost.MultiIndex is a great
library and can do all kinds of wonderful things. But I would still like to see
a bidirectional map (boost::bimap) written as a wrapper around it to
get an easy and specialized interface.
]]
[*Pavel]
[:['
Bimap is available in libs/multi-index/examples/bimap.cpp.
]]
[*Thorsten]
[:['
Right, but the real value comes when somebody designs a nice
STL-like interface and write docs etc, at least that was my point.
]]
[*Dave]
[:['
IMO Thorsten is exactly right. This is precisely the sort of
thing that could be added to the library as part of its ongoing maintenance
and development (without review, of course).
]]
[*Joaquin]
[:['
Thorsten, we have talked about this privately in the past,
but I feel like bringing it to the list in the hope of getting the attention
of potential contributors:
]]
[:['
There are some data structures buildable with B.MI which are regarded as
particularly useful or common, like for instance the bidirectional map or
bimap. A lean and mean implementation is provided in the aforementioned
example, but certainly a much carefully crafted interface can be provided
keeping B.MI as the implementation core: operator\[\], selection of
1-1/1-N/N-1/N-N variants, hashing/ordering, etc.
]]
[:['
I'm afraid I don't have the time to pursue this, as the current roadmap for
core features of B.MI is taking all the spare time I can dedicate to the
library. For this reason, I would love to see some volunteer jumping in who
can develop this and other singular containers using B.MI (a cache container
comes to mind) and then propose the results here either as a stand alone
library of as part of B.MI --I'd prefer the former so as to keep the size
of B.MI bounded.
]]
[:['
If there's such a volunteer I can provide her with some help/mentoring. I also
wonder whether this is a task suitable to be proposed for Google Summer of
Code.
]]
[*Thorsten]
[:['
I think it would be good for SOC. All the really hard things
are taken care of by B.MI, and so it seems reasonable for a student to be able
to fill in the details.
]]
[*Dave]
[:['
Great!
]]
[*Jeff]
[:['
Please write a proposal!
]]
[*Joaquin]
[:['
I've just done so:
]]
[blurb *Specialized containers with Boost.MultiIndex*
*Introduction*
Boost.MultiIndex allows the construction of complex data structures involving
two or more indexing mechanisms on the same set of elements. Out of the
unlimited range of possible data structures specifiable within
Boost.MultiIndex, some particular configurations arise recurrently:
*a.* A bidirectional map or bimap is a container of elements of type pair<T,Q>
where fast look up is provided both for the T and the Q field,
in contrast with a regular STL map which only allows for fast look up on T.
*b.* An MRU (most recently used) list keeps the n last referenced elements:
when a new item is inserted and the list has reached its maximum length, the
oldest element is erased, whereas if an insertion is tried of a preexistence
element, this gets promoted to the first position. MRU lists can be used to
implement dynamic caches and the kind of behavior exhibited by programs
featuring a "Recent files" menu command, for instance.
Although Boost.MultiIndex provides the mechanisms to build these common structures,
the resulting interface can be cumbersome and too general in comparison with
specialized containers focusing on such particular structures.
*Goal*
To write a library of specialized containers like the ones described above, using
Boost.MultiIndex as the implementation core. Besides bimap and MRU list, the student
can also propose other specialized containers of interest in the community. It is
expected that the library meets the standards of quality required by Boost for an
eventual inclusion in this project, which implies a strong emphasis on interface
design, documentation and unit testing; the mentor will be guiding the student
through the complete cycle from specification and requirements gathering to
documentation and actual coding. The final result of the project must then contain:
*a.* Source code following
[@http://boost.org/more/lib_guide.htm#Guidelines Boost programming guidelines].
*b.* User documentation. Requirements on the format are loose, though the
[@http://www.boost.org/tools/quickbook/doc/html/index.html QuickBook] format is
gaining acceptance within Boost.
*c.* Complete set of unit tests powered by
[@http://boost.sourceforge.net/boost-build2/ Boost Build System V2].
*Requirements*
*a.* Intermediate-to-high level in C++, with emphasis in generic programming
(templates).
*b.* Knowledge of the STL framework and design principles. Of course, knowledge
of Boost in general and Boost.MultiIndex in particular is a big plus.
*c.* Acquaintance with at least two different C++ programming environments.
*d.* Some fluency in the English language; subsequent reviews of the documentation
can help smooth rough edges here, though.
*e.* A mathematical inclination and previous exposure to a formal Algorithms course
would help very much.
*f.* A craving for extreme quality work.
*Benefits for the student*
The student taking on this project will have the opportunity to learn the complete
process of software production inside a highly regarded C++ open source institution,
and even see her work included in Boost eventually. The completion of the project
involves non-trivial problems in C++ interface design and so-called modern C++
programming, high quality user documentation and unit testing. The student will
also learn, perhaps to her surprise, that most of the time will be spent gathering
and trying ideas and, in general, thinking, rather than writing actual code.
]
[*Matias]
[:['
I am planning to submit an application to SoC. I will love to make real
the specialized containers you mention and try to include some useful others.
]]
[:[^
And then... after long hours of coding (and fun) this library saw the light.
]]
[:__BOOST_BIMAP_LOGO__]
[endsect]
[endsect]

99
doc/introduction.qbk Executable file
View File

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

60
doc/jamfile.v2 Executable file
View File

@@ -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)
import quickbook ;
xml bimap
:
bimap.qbk
;
boostbook standalone
:
bimap
:
<xsl:param>toc.max.depth=4
<xsl:param>toc.section.depth=4
<xsl:param>chunk.section.depth=2
;
# This generate the doxydocs and write "bimap.hdt". Delete this file if you want to regenerate the doxydocs again
# TODO: Learn how to call user doxygen path rather than doxygen directly.
import directdoxygen ;
html-doxydocs bimap.hdt : bimap.hdf ;
# Apply style...
# TODO: Learn how to call user copy utility path rather than cp directly.
import notfile ;
notfile apply_style : @apply ;
actions apply
{
mkdir html/images
mkdir html/images/toc
mkdir html/images/bimap
mkdir html/images/extern
mkdir html/images/people
mkdir html/images/callouts
cp style/template/images/*.png html/images/
cp style/template/images/toc/*.png html/images/toc/
cp style/template/images/bimap/*.png html/images/bimap/
cp style/template/images/extern/*.png html/images/extern/
cp style/template/images/people/*.png html/images/people/
cp style/template/images/callouts/*.png html/images/callouts/
cp style/template/boostbook.css html/boostbook.css
cp style/template/index.html html/index.html
cp style/template/doxydoc/doxygen.css html/doxydoc/doxygen.css
cp style/template/doxydoc/tabs.css html/doxydoc/tabs.css
cp style/template/doxydoc/tab_r.gif html/doxydoc/tab_r.gif
cp style/template/doxydoc/tab_l.gif html/doxydoc/tab_l.gif
cp style/template/doxydoc/tab_b.gif html/doxydoc/tab_b.gif
}

19
doc/performance.qbk Executable file
View File

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

177
doc/quick_tutorial.qbk Executable file
View File

@@ -0,0 +1,177 @@
[/license
Boost.Bimap
Copyright (c) 2006-2007 Matias Capeletto
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]
[/ QuickBook Document version 1.4 ]
[section One minute tutorial]
[heading What is a bimap?]
A Bimap is a data structure that represents bidirectional relations between
elements of two collections. The container is designed to work as two opposed STL maps. A bimap between a collection `X` and a collection `Y` can be viewed as a map from `X` to `Y` (this view will be called the ['left map view]) or as a map from `Y` to `X` (known as the ['right map view]). Additionally, the bimap can also be viewed as a set of relations between `X` and `Y` (named the ['collection of relations view]).
The following code creates an empty bimap container:
typedef bimap<X,Y> bm_type;
bm_type bm;
Given this code, the following is the complete description of the resulting bimap.
[footnote A type is ['signature-compatible] with other type if it has the same
signature for functions and metadata. Preconditions, postconditions and the order
of operations need not be the same.
]
* `bm.left` is signature-compatible with `std::map<X,Y>`
* `bm.right` is signature-compatible with `std::map<Y,X>`
* `bm` is signature-compatible with `std::set< relation<X,Y> >`
__SIMPLE_BIMAP__
You can see how a bimap container offers three views over the same collection of bidirectional relations.
The `relation` class represents two related elements. The two values are
named left and right to express the symmetry of this type.
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 Step by step]
[import ../example/step_by_step.cpp]
A convinience header is avaiable in the boost directory:
#include <boost/bimap.hpp>
Lets define a bidirectional map between integers and strings:
[code_step_by_step_definition]
[heading The collection of relations view]
Remember that `bm` alone can be used as a set of relations.
We can insert elements or iterate over them using this view.
[code_step_by_step_set_of_relations_view]
[heading The left map view]
`bm.left` works like a `std::map< int, std::string >`. We use it
in the same way we will use a standard map.
[code_step_by_step_left_map_view]
[heading The right map view]
`bm.right` works like a `std::map< std::string, int >`. It is
important to note that the key is the first type and the data
is the second one, exactly as with standard maps.
[code_step_by_step_right_map_view]
[heading Differences with std::map]
The main difference between bimap views and their standard containers counterparts
is that, because of the bidirectional nature of a bimap, the values stored in
it can not be modified directly using iterators.
For example, when a `std::map<X,Y>` iterator is dereferenced the return type is
`std::pair<const X, Y>`, so the following code is valid:
`m.begin()->second = new_value;`.
However dereferencing a `bimap<X,Y>::left_iterator` returns a type that is
['signature-compatible] with a `std::pair<const X, const Y>`
bm.left.find(1)->second = "1"; // Compilation error
If you insert `(1,"one")` and `(1,"1")` in a `std::map<int,std::string>` the second insertion will have no effect. In a `bimap<X,Y>` both keys have to remain unique. The insertion may fail in other situtions too. Lets see an example
bm.clear();
bm.insert( bm_type::value_type( 1, "one" ) );
bm.insert( bm_type::value_type( 1, "1" ) ); // No effect!
bm.insert( bm_type::value_type( 2, "one" ) ); // No effect!
assert( bm.size() == 1 );
[heading A simple example]
Look how you can reuse code that is intend to be used with std::maps, like the
print_map function in this example.
[@../../example/simple_bimap.cpp Go to source code]
[code_simple_bimap]
The output of this program will be the following:
[pre
[^The number of countries is 4]
[^The winner is Argentina]
[^Countries names ordered by their final position:]
[^1) Argentina]
[^2) Spain]
[^3) Germany]
[^4) France]
[^Countries names ordered alphabetically along with their final position:]
[^Argentina ends in position 1]
[^France ends in position 4]
[^Germany ends in position 3]
[^Spain ends in position 2]
]
[heading Continuing the journey]
For information on function signatures, see any standard library
documentation or read the [link boost_bimap.reference reference] section of
this documentation.
[caution
Be aware that a bidirectional map is only signature-compatible with standard
containers. Some functions may give different results, such as in the case of
inserting a pair into the left map where the second value conflicts with a
stored relation in the container. The functions may be slower in a bimap
because of the duplicated constraints. It is strongly recommended that
you read [link boost_bimap.the_tutorial The full tutorial] if you intend to
use a bimap in a serious project.
]
[endsect]

908
doc/rationale.qbk Executable file
View File

@@ -0,0 +1,908 @@
[/license
Boost.Bimap
Copyright (c) 2006-2007 Matias Capeletto
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]
[/ QuickBook Document version 1.4 ]
[section Rationale]
This section assumes that you have read all other sections, the most of
important of which being ['tutorial], ['std::set theory] and the ['reference],
and that you have tested the library. A lot of effort was invested in
making the interface as intuitive and clean as possible. If you
understand, and hopefully like, the interface of this library, it will
be a lot easier to read this rationale. The following section is little
more than a rationale. This library was coded in the context of the
Google SoC 2006 and the student and mentor were in different continents.
A great deal of email flowed between Joaquin and Matias. The juiciest
parts of the conversations where extracted and rearranged here.
[note To browse the code, you can use the [@doxydoc/index.html ['Bimap Complete Reference]], a
doxygen-powered document targeted at developers.
]
[section General Design]
The initial explanation includes few features. This section aims to
describe the general design of the library and excludes details of those
features that are of lesser importance; these features will be
introduced later.
The design of the library is divided into two parts. The first is the
construction of a [^relation] class. This will be the object stored and
managed by the [^multi_index_container] core. The idea is to make this
class as easy as possible to use, while making it efficient in terms of
memory and access time. This is a cornerstone in the design of
[*Boost.Bimap] and, as you will see in this rationale, the rest of the
design follows easily.
The following interface is necessary for the [^relation] class:
typedef -unspecified- TA; typedef -unspecified- TB;
TA a, ai; TB b, bi;
typedef relation< TA, TB > rel;
STATIC_ASSERT( is_same< rel::left_type , TA >::value );
STATIC_ASSERT( is_same< rel::right_type, TB >::value );
rel r(ai,bi);
assert( r.left == ai && r.right == bi );
r.left = a; r.right = b;
assert( r.left == a && r.right == b );
typedef pair_type_by< member_at::left , rel >::type pba_type;
STATIC_ASSERT( is_same< pba_type::first_type , TA >::value );
STATIC_ASSERT( is_same< pba_type::second_type, TB >::value );
typedef pair_type_by< member_at::right, rel >::type pbb_type;
STATIC_ASSERT( is_same< pbb_type::first_type , TB >::value );
STATIC_ASSERT( is_same< pbb_type::second_type, TA >::value );
pba_type pba = pair_by< member_at::left >(r);
assert( pba.first == r.left && pba.second == r.right );
pbb_type pbb = pair_by< member_at::right >(r);
assert( pbb.first == r.right && pbb.second == r.left );
__RELATION__
Although this seems straightforward, as will be seen later, it is the
most difficult code hack of the library. It is indeed very easy if we
relax some of the efficiency constraints. For example, it is trivial if
we allow a relation to have greater size than the the sum of those of
its components. It is equally simple if access speed is not important.
One of the first decisions made about [*Boost.Bimap] was, however, that, in
order to be useful, it had to achieve zero overhead over the wrapped
[*Boost.MultiIndex] container. Finally, there is another constraint that
can be relaxed: conformance to C++ standards, but this is quite
unacceptable. Let us now suppose that we have coded this class, and it
conforms to what was required.
The second part is based on this [^relation] class. We can now view the
data in any of three ways: `pair<A,B>`, `relation<A,B>` and `pair<B,A>`.
Suppose that our bimap supports only one-to-one relations. (Other
relation types are considered additional features in this design.)
The proposed interface is very simple, and it is based heavily on the
concepts of the STL. Given a `bimap<A,B> bm`:
# `bm.left` is signature-compatible with a `std::map<A,B>`
# `bm.right` is signature-compatible with a `std::map<B,A>`
# `bm` is signature-compatible with a `std::set<relation<A,B> >`
__SIMPLE_BIMAP__
This interface is easily learned by users who have a STL background, as
well as being simple and powerful. This is the general design.
[heading Relation Implementation]
This section explains the details of the actual [^relation] class implementation.
The first thing that we can imagine is the use of an [^union]. Regrettably,
the current C++ standard only allows unions of POD types. For the views,
we can try a wrapper around a `relation<A,B>` that has two references
named first and second that bind to `A` and `B`, or to `B` and `A`.
relation<TA,TB> r;
const_reference_pair<A,B> pba(r);
const_reference_pair<B,A> pbb(r);
It is not difficult to code the relation class using this, but two
references are initialized at every access and using of `pba.first` will
be slower in most compilers than using `r.left` directly . There is
another hidden drawback of using this scheme: it is not
iterator-friendly, since the map views iterators must be degraded to
['Read Write] instead of ['LValue]. This will be explained later.
At first, this seems to be the best we can do with the current C++
standard. However there is a solution to this problem that does not
conform very well to C++ standards but does achieve zero overhead in
terms of access time and memory, and additionally allows the view
iterators to be upgraded to ['LValue] again.
In order to use this, the compiler must conform to a
layout-compatibility clause that is not currently in the standard but is
very natural. The additional clause imposes that if we have two classes:
struct class_a_b
{
Type1 name_a;
Type2 name_b;
};
struct class_b_a
{
Type1 name_b;
Type2 name_a;
};
then the storage layout of [^class_a_b] is equal to the storage layout of
[^class_b_a]. If you are surprised to learn that this does not hold in a
standards-compliant C++ compiler, welcome to the club. It is the natural
way to implement it from the point of view of the compiler's vendor and
is very useful for the developer. Maybe it will be included in the
standard some day. Every current compiler conforms to this.
If we are able to count on this, then we can implement an idiom called
[^mutant]. The idea is to provide a secure wrapper around [^reinterpret_cast].
A class can declare that it can be viewed using different view classes
that are storage-compatible with it. Then we use the free function
[^mutate<view>(mutant)] to get the view. The `mutate` function checks at
compile time that the requested view is declared in the mutant views list.
We implement a class name `structured_pair` that is signature-compatible
with a `std::pair`, while the storage layout is configured with a third
template parameter. Two instances of this template class will provide
the views of the relation.
The thing is that if we want to be standards-compliant, we cannot use
this approach. It is very annoying not to be able to use something that
we know will work with every compiler and that is far better than
alternatives. So -- and this is an important decision -- we have to find
a way to use it and still make the library standards-compliant.
The idea is very simple. We code both approaches: the
const_reference_pair-based and the mutant-based, and use the mutant
approach if the compiler is compliant with our new layout-compatible
clause. If the compiler really messes things up, we degrade the
performance of the bimap a little. The only drawback here is that, while
the mutant approach allows to make ['LValue] iterators, we have to degrade
them to ['Read Write] in both cases, because we require that the same code
be compilable by any standards-compliant compiler.
[heading Bimap Implementation]
The core of bimap will be obviously a `multi_index_container`. The basic
idea to tackle the implementation of the bimap class is to use
[^iterator_adaptor] to convert the iterators from Boost.MultiIndex to the
`std::map` and `std::set` behaviour. The `map_view` and the `set_view` can be
implemented directly using this new transformed iterators and a wrapper
around each index of the core container. However, there is a hidden
idiom here, that, once coded, will be very useful for other parts of
this library and for Boost.MRU library. Following the ideas from
`iterator_adaptor`, Boost.Bimap views are implemented using a
[^container_adaptor]. There are several template classes (for example
`map_adaptor` and `set_adaptor`) that take a `std::map` signature-conformant
class and new iterators, and adapt the container so it now uses this
iterators instead of the originals. For example, if you have a
`std::set<int*>`, you can build other container that behaves exactly as a
`std::set<int>` using `set_adaptor` and [^iterator_adaptor]. The combined use
of this two tools is very powerful. A [^container_adaptor] can take classes
that do not fulfil all the requirements of the adapted container. The
new container must define these missing functions.
[endsect]
[section Additional Features]
[heading N-1, N-N, hashed maps]
This is a very interesting point of the design. The framework introduced
in ['std::set theory] permits the management of the different constraints
with a very simple and conceptual approach. It is easy both to remember
and to learn. The idea here is to allow the user to specify the collection type
of each key directly. In order to implement this feature, we have to
solve two problems:
* The index types of the `multi_index_container` core now depends on
the collection type used for each key.
* The map views now change their semantics according to the collection type
chosen.
Boost.Bimap relies heavily on Boost.MPL to implement all of the
metaprogramming necessary to make this framework work. By default, if
the user does not specify the kind of the set, a `std::set` type is used.
__BIMAP_STRUCTURES__
[heading Collection type of relation constraints]
The constraints of the bimap set view are another very important
feature. In general, Boost.Bimap users will base the set view type on
one of the two collection types of their keys. It may be useful however to give
this set other constraints or simply to order it differently. By
default, Boost.Bimap bases the collection type of relations on the left collection
type, but the user may choose between:
* left_based
* right_based
* set_of_relation<>
* multiset_of_relation<>
* unordered_set_of_relation<>
* unordered_multiset_of_relation<>
* list_of
* vector_of
In the first two cases, there are only two indices in the
`multi_index_core`, and for this reason, these are the preferred options.
The implementation uses further metaprogramming to define a new index if
necessary.
[/
[heading Hooking Data]
This is one of the things that makes Boost.Bimap very appealing in
tackling a problem. In general, programmers use maps to access
information quickly. Boost.Bimap allows the user to hook data inside the
bimap so that it is not necessary to maintain another map. The
implementation is based heavily on metaprogramming.
]
[heading Tagged]
The idea of using tags instead of the [^member_at::side] idiom is very
appealing since code that uses it is more readable. The only cost is
compile time. ['boost/bimap/tagged] is the implementation of a non-invasive
tagged idiom. The [^relation] class is built in such a way that even when
the user uses tags, the [^member_at::side] idiom continues to work. This is
good since an user can start tagging even before completing the coding
of the algorithm, and the untagged code continues to work. The
development becomes a little more complicated when user-defined tags are
included, but there are many handy metafunctions defined in the [^tagged]
idiom that help to keep things simple enough.
__TAGGED__
[endsect]
[section Code]
You can browse the code using the [@doxydoc/index.html [*Boost.Bimap doxygen docs]].
The code follows the [@http://www.boost.org/more/lib_guide.htm Boost Library Requirement and Guidelines] as
closely as possible.
[table folders in boost/bimap
[[name][what is inside?]]
[[/ ][user level header files ]]
[[tagged/ ][tagged idiom ]]
[[relation/ ][the bimap data ]]
[[container_adaptor/ ][easy way of adapting containers ]]
[[views/ ][bimap views ]]
[[property_map/ ][support for property map concept ]]
]
[table folders in each folder
[[name][what is inside?]]
[[ ][class definitions]]
[[support/ ][optional metafunctions and free functions]]
[[detail/ ][things not intended for the user's eyes]]
]
[endsect]
[section The student and the mentor]
[tip It is a good idea to read the original
[@http://h1.ripway.com/mcape/boost/libs/misc/ Boost.Misc SoC proposal] first.]
[:[^- The discussion starts with Joaquin trying to strip out the "misc" name out of the library -]]
__JOAQUIN_PHOTO__
[*Joaquin]
[:['
Thinking about it, the unifying principle of MISC containers is perhaps
misleading: certainly all miscs use multi-indexing internally, but this does
not reflect much in the external interface (as it should be, OTOH). So, from
the user's point of view, miscs are entirely heterogeneous beasts. Moreover,
there isn't in your proposal any kind of global facility common to all miscs.
What about dropping the misc principle and working on each container as a
separate library, then? You'd have boost::bimap, boost::mru, etc, and no common
intro to them. This also opens up the possibility to add other containers to
the suite which aren't based on B.MI. What's your stance on this? Do you see a
value in keeping miscs conceptually together?
]]
__MATIAS_PHOTO__
[*Matias]
[:['
As the original proposal states only two containers (bimap and mru set) both
based in B.MI, it was straight forward to group them together. When I was
writing the SoC proposal I experienced a similar feeling when the two families
begin to grow. As you say, the only common denominator is their internal
implementation. I thought a bit about a more general framework to join this two
families (and other internally related ones) and finally came up with an idea:
Boost.MultiIndex! So I think that it is not a good idea to try to unify the two
families and I voted in favor of get rid of the misc part of boost::misc::bimap
and boost::misc::mru. Anyway, for my SoC application it seems OK to put the
two families in the same project because although from the outside they are
completely unrelated, the work I will have to do in order to build the libraries
will be consistent and what I will learn coding the bimap family will be used
when I start to code the mru family. When the mru family is in place, I will
surely have learnt other things to improve the bimap group.
]]
[:['
On the other hand, I think it will be useful for the general user to
have at least some document linked in the B.MI documentation that
enumerates the most common cases of uses (a bimap and an mru set for
example) and points where to find clean implementation for this useful
containers. For now, a link to boost::bimap and other one to boost::mru
will suffice. If you think about the title of such a document,
you will probably come up with something like: Common Multi Index
Specialized Containers, and we are back to our misc proposal.
So, to order some ideas:
]]
[:['- A new family of containers that can be accessed by both key will
be created. (boost::bimap)]]
[:['- A new family of time aware containers will see the light.
(boost::mru)]]
[:['- A page can be added to B.MI documentation, titled misc that links
this new libraries.]]
[:['
This is a clearer framework for the user. They can use a mru container
without hearing about Boost.MultiIndex at all.
And B.MI users will get some of their common containers already
implemented with an STL friendly interface in other libraries.
And as you stated this is more extensible because opens the door to use
other libraries in bimap and mru families than just Boost.MultiIndex
without compromising the more general boost framework.
The word "misc" it is going to disappear from the code and
the documentation of bimap and mru. From now on the only use for it will be to
identify our SoC project. I am thinking in a name for the bimap library.
What about Boost.BidirectionalMap? Ideas?
]]
[*Joaquin]
[:['
Yes, Boost.Bimap. In my opinion, bimap is a well known name
in the Boost and even in the C++ community. It sounds and is short. Why not to
vindicate yourself as the owner of this name?
]]
[^- Then after a week of work -]
[*Matias]
[:['
Now that Boost.Bimap is getting some shape, I see that as
you have told me, we must offer a "one_to_many_map" and a "multi_bimap"
as part of the library. The framework I am actually working allowed to
construct this kind of bidirectional maps and it is easy to understand from
the user side.
]]
[*Joaquin]
[:['
OK, I am glad we agree on this point.
]]
[*Matias]
[:['
With respect to the symmetry of the key access names, I have to
agree that there is not much a difference between the following ones:
]]
[:['- to - from]]
[:['- to - b]]
[:['- 0 - 1]]
[:['- left - right]]
[:['
In my opinion it is a matter of taste, but left/right sounds more symmetrical than
the others.
]]
[*Joaquin]
[:['
I like very much the left/right notation, it is very simple to
remember and it is a lot more symmetrical than to/from.
]]
[*Matias]
[:['
At first my idea was to obtain ease of use hiding the B.MI
core, making it more STL-intuitive. Nevertheless I have realized
that B.MI is a lot more coherent and easy to use that I had imagined. This
makes me think again in the problem. In the design that I am coding now, bimap
*is-a* multi_index_container specializes with a data type very comfortable
called bipair, that can be seen like any of the two maps that integrates it
using map views. This scheme has great benefits for users:
]]
[:['
- If the user already knows B.MI, he can take advantage of the tools that
it provides and that are not present in the STL containers. In addition, in some
cases the use to indices to see the data can be very useful.
]]
[:['
- If the user does not know anything about B.MI but have an STL framework,
the learning curve is reduced to understand the bimap instantiation and how a
is obtained the desired map view.
]]
[:['
Another very important benefit holds: All the algorithms done for
B.MI continues to work with Boost.Bimap and if B.MI continues growing, bimap
grow automatically.
]]
[*Joaquin]
[:['
Umm... This is an interesting design decision, but
controversial in my opinion. Basically you decide to expose the
implementation of bimap; that has advantages, as you stated, but also
a nonsmall disadvantage: once *you have documented* the implementation,
it is not possible to change it anymore. It is a marriage with B.MI without
the chance of divorce. The other possibility, to hide the implementation and
to duplicate and document the provided functionality, explicitly or
implicitly due to the same characteristics of the implementation, is
of course heavier to maintain, but it gives a degree of freedom to change
the guts of your software if you need to. Do not take this like a frontal
objection, but I think that it is quite important design decision, not only
in the context of bimap but in general.
]]
[*Matias]
[:['
You are quite right here. I think we have to choose the hardest
path and hide the B.MI core from the user. I am sending you the first draft of
bimap along with some documentation.
]]
[^- This completes the second week, the documentation was basically the first
section of this rationale -]
[*Joaquin]
[:['
I must confess that I am beginning to like what I see.
I am mathematical by vocation, and when I see symmetry in a formulation
I believe that it is in the right track.
]]
[*Matias]
[:['
We are two mathematicians by vocation then.
]]
[*Joaquin]
[:['
I think that the part of std::set theory is very clear.
To me, it turns out to me somewhat strange to consider the rank of a map
(values X) like a std::set, but of course the formulation is consistent.
]]
[*Matias]
[:['
I like it very much, it can be a little odd at first, but
now that I have get used to it, it is very easy to express in the code my
contrains on the data, and I believe that if somebody reads the code and
sees the bimap instantiation he is not going to have problems understanding
it. Perhaps it is easier to understand it if we use your notation:
ordered_nonunique, unordered_unique, but this goes against our STL facade.
In my opinion the user that comes from STL must have to learn as less as possible.
]]
[*Joaquin]
[:['
Considering a relation like a `struct {left, right}`
is clean and clear. If I understand it well, one relation has views of type
`pair{first, second}`, is this correct?
]]
[*Matias]
[:['
Yes, I believe that the left/right notation to express symmetry
is great. I believe that to people is going to love it.
]]
[*Joaquin]
[:['
OK, perfect. I likes this very much:
]]
[:['- bm.left is compatible with std::map<A,B>]]
[:['- bm.right is compatible with std::map<B,A>]]
[:['- bm is compatible with std::set<relation<A,B>>]]
[:['
It is elegant and symmetric. I feel good vibrations here.
]]
[*Matias]
[:['
Great!
]]
[*Joaquin]
[:['
Moving on, the support for N-1, N-N, and hashed index is very easy
to grasp, and it fits well in framework.
However I do not finish to understand very well the "set<relation> constraints" section.
Will you came up with some examples of which is the meaning of the different
cases that you enumerate?
]]
[*Matias - ]
[:['
Yes, I mean:
]]
[:['- based on the left]]
[:['- based on the right]]
[:['
The bimap core must be based on some index of multi index. If the index
of the left is of the type hash, then in fact the main view is going
to be an unordered_set< relation<A,B> >. Perhaps this is not what the user
prefers and he wants to base its main view on the right index.
]]
[:['- set_of_relation ]]
[:['- multiset_of_relation ]]
[:['- unordered_set_of_relation ]]
[:['- unordered_multiset_of_relation ]]
[:['
However, if both of them are hash indexes, the user may want the main view
to be ordered. As we have a B.MI core this is very easy to support, we just have
to add another index to it.
]]
[*Joaquin]
[:['
I understand it now. OK, I do not know if we have to include this
in the first version, is going to be a functionality avalanche!
]]
[*Matias]
[:['
The user is not affected by the addition of this functionality,
because by default it will be based on the left index that is a very natural
behaviour. I do not think that this is functionality bloat, but I agree with
you that it is a functionality avalanche.
]]
[*Joaquin]
[:['
There are restrictions between the left and right set types
and the possible main view set types. For example if some of the index is
of unique type, then the main view cannot be of type multiset_of_relation.
To the inverse one, if the main view is of type set_of_relation the left and
the right index cannot be of type multi_set. All this subject of the unicity
constrictions and the resulting interactions between indexes is one of the subtle
subjects of B.MI.
]]
[*Matias]
[:['
This can be checked at compile time and informed as an error
in compile time.
]]
[*Joaquin]
[:['
It can be interesting.
]]
[^- And right when everything seems to be perfect... - ]
[*Joaquin]
[:['
I have some worse news with respect to mutant, it is very a
well designed and manageable class, unfortunately, C++ does not guarantee
layout-compatibility almost in any case. For example, the C++ standard does
not guarantee that the classes `struct{T1 a; T2 b;}` and `struct{T1 b; T2 a;}`
are layout-compatible, and therefore the trick of reinterpret_cast is an
undefined behavior. I am with you in which that in the 100% of the cases
this scheme will really work, but the standard is the standard. If you can
look the layout-compatibility subject in it (http://www.kuzbass.ru/docs/isocpp/).
As you see, sometimes the standard is cruel. Although mutant seems a lost case,
please do not hurry to eliminate it. We will see what can be done for it.
]]
[*Matias]
[:['
I read the standard, and you were right about it. Mutant was an implementation
detail. It is a pity because I am sure that it will work perfect in any compiler.
Perhaps the standard becomes more strict some day and mutant returns to life...
We can then try a wrapper around a relation<A,B> that have two references named
first and second that bind to A and B, or B and A.
]]
``
relation<TA,TB> r;
const_reference_pair<A,B> pba(r);
const_reference_pair<B,A> pbb(r);
``
[:['
It is not difficult to code the relation class in this way but two references
are initialized with every access and the use of `pba.first` will be slower
than `r.left` in most compilers. It is very difficult to optimize this kind of
references.
]]
[*Joaquin]
[:['
This workaround is not possible, due to technical problems with
the expected behavior of the iterators. If the iterators of bm.left are of
bidirectional type, then standard stated that it have to return an object of type
const value_type& when dereferenced. You will have to return a const_reference_pair
created in the flight, making it impossible to return a reference.
]]
[*Matias]
[:['
I understand... I have workaround for that also but surely
the standard will attack me again! We must manage to create the class relation
that responds as we want, the rest of the code will flow from this point.
This clear separation between the relation class and the rest of the library,
is going to help to us to separate the problems and to attack them better.
]]
[*Joaquin]
[:['
What workaround? It already pricks my curiosity,I have dedicated
a long time to the subject and I do not find any solution except that we
allow the relation class to occupy more memory.
]]
[*Matias]
[:['
We must achieve that the relation<A,B> size equals the pair<A,B> size
if we want this library to be really useful. I was going to write my workaround and
I realized that It does not work. Look at this:
http://www.boost.org/libs/iterator/doc/new-iter-concepts.html
Basically the problem that we are dealing is solved if we based our iterators on
this proposal. The present standard forces that the bidirectional iterators also
are of the type input and output. Using the new concepts there is no inconvenient
in making our iterators "Readable Writable Swappable Bidirectional Traversal".
Therefore the const_reference_pair returns to be valid.
]]
[*Joaquin]
[:['
It is correct in the sense that you simply say that
your iterators are less powerful than those of the std::map. It is
not that it is wrong, simply that instead of fixing the problem, you
confess it.
]]
[*Matias]
[:['
OK, but in our particular case; What are the benefits
of offering a LValue iterator against a Read Write iterator?
It does not seem to me that it is less powerful in this case.
]]
[*Joaquin]
[:['
The main problem with a ReadWrite is that the following thing:
`value_type * p=&(*it);`
fails or stores a transitory direction in p. Is this important in the real life?
I do not know. How frequently you store the direction of the elements of a map?
Perhaps it is not very frequent, since the logical thing is to store the
iterators instead of the directions of the elements.
Let us review our options:
]]
[:['
1. We used mutant knowing that is not standard, but of course it is
supported in the 100% of the cases.
]]
[:['
2. We used const_reference_pair and we declared the iterators not LValue.
]]
[:['
3. We found some trick that still we do not know. I have thus been playing
with unions and things, without much luck.
]]
[:['
4. We leverage the restriction that views have to support the first, second
notation. If we made this decision, there are several possibilities:
]]
[:['
''' '''a. The left map has standard semantics first/second while the right map
has the inverse semantics.
]]
[:['
''' '''b. Instead of first and second we provide first() and second(), with
which the problem is trivial.
]]
[:['
''' '''c. The map view do not support first/second but left/right as the
father relation
]]
[:['
5. We solve the problem using more memory than sizeof(pair<A,B>).
]]
[:['
In any case, I would say that the only really unacceptable option is the last one.
]]
[*Matias]
[:['
Lets see.
]]
[:['
1. I want the "standard compliant" label in the library.
]]
[:['
2. This is the natural choice, but knowing that there is another option
that always works and it is more efficient is awful.
]]
[:['
3. I have also tried to play with unions, the problem is that the union members
must be POD types.
]]
[:['
4. This option implies a big lost to the library.
]]
[:['
5. Totally agree.
]]
[:['
I want to add another option to this list. Using metaprogramming,
the relation class checks if the compiler supports the mutant idiom.
If it supports it then it uses it and obtains zero overhead
plus LValue iterators, but if it do not supports it then uses
const_reference_pair and obtains minimum overhead with ReadWrite iterators.
This might be controversial but the advantages that mutant offers are very big
and the truth is that I do not believe that in any actual compiler this idiom is
not supported. This scheme would adjust perfectly to the present standard
since we are not supposing anything. The only drawback here is that although
the mutant approach allows to make LValue iterators we have to degrade they
to Read Write in both cases, because we want that the same code can be
compiled in any standard compliant compiler.
]]
[^- Hopefully we find our way out of the problem -]
[*Joaquin]
[:['
Changing the subject, I believe that the general concept of hooking data
is good, but I do not like the way you implement it. It has to be easy
to migrate to B.MI to anticipate the case in that Boost.Bimap becomes insufficient.
It is more natural for a B.MI user that the data is accessed without the indirection
of `.data`. I do not know how this can be articulated in your framework.
]]
[*Matias]
[:['
I have a technical problem to implement the data_hook in this way.
If the standard would let us use the mutant idiom directly, I can implement it
using multiple inheritance. But as we must use const_reference_pair too, It becomes
impossible for me to support it. We have three options here:
]]
[:['
1) relation { left, right, data } and pair_view { first, second, data }
]]
[:['
- This is more intuitive within the bimap framework, since it does not
mix the data with the index, as a table in a data base does, but gives more importance to
the index.
]]
[:['
- It is not necessary that the user puts the mutable keyword in each member of
the data class.
]]
[:['
- This moves away just a little bit from B.MI because the model
of it is similar to a table, but it continues to exist a clear path of migration.
]]
[:['
2) relation { left,right, d1,d2... dn } and pair_view { first, second, data }
]]
[:['
- The path to B.MI is the one you have proposed.
]]
[:['
- It is very asymmetric. It is necessary to explain that the views are
handled different that the relation.
]]
[:['
- The user must place the mutable keyboards in the data class.
]]
[:['
3) Only relation { left,right, d1,d2... dn }
]]
[:['
- Simple migration path to B.MI.
]]
[:['
- You are not able to access the hooked data from the views.
]]
[:['
My vote goes to the first proposal.
]]
[*Joaquin]
[:['
Yes, the first option is the one that less surprises hold to the user.
I also vote for 1.
]]
[^- The third week was over -]
[*Matias]
[:['
There is still one problem that I have to solve. I need to
know if it is necessary to create a map_view associated to nothing. If
it is necessary there are two options: that it behaves as an empty container or
that it throws an exception or assert when trying to use it. If it is not necessary,
the map_view is going to keep a reference instead of a pointer.
To me, the map_view always must be viewing something. In the case of the iterators
being able to create them empty, makes them easy to use in contexts that require
constructors by default, like being the value_type of a container, but I do not
believe that this is the case of map_view.
]]
[*Joaquin]
[:['
How would an empty map_view be useful? My intuition is like yours,
map_view would have to be always associate to something. If we wished to obtain
the semantics "is associated or not" we can use a pointer to a map_view.
]]
[*Matias]
[:['
OK, then you agree to that map_views stores a reference instead
of a pointer?
]]
[*Joaquin]
[:['
It depends on the semantics you want to give to map_views, and in
concrete to the copy of map_views.
]]
``
map_view x=...;
map_view y=...;
x=y;
``
[:['
What is supposed to do this last line?
]]
[:['
1. Rebinding of x, that is to say, x points at the same container that y.
]]
[:['
2. Copy of the underlying container.
]]
[:['
If you want to implement 1, you cannot use references internally.
If you want to implement 2, it is almost the same to use a reference or a pointer.
]]
[*Matias]
[:['
If I want that they behave exactly as std::maps then I must go for 2.
But if I think they as "views" of something, I like 1. The question is complicated.
I add another option:
]]
[:['
3. Error: operator= is declare as private in boost::bimap::map_view std_container
]]
[:['
Also What happens with `std_container = view;`? and with `view = std_container;`?
]]
[endsect]
[endsect]

64
doc/reference.qbk Executable file
View File

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

528
doc/reference/bimap.qbk Executable file
View File

@@ -0,0 +1,528 @@
[/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_value_type;
typedef ``['-unspecified-]`` left_key_type;
typedef ``['-unspecified-]`` left_data_type;
typedef ``['-unspecified-]`` left_iterator;
typedef ``['-unspecified-]`` left_const_iterator;
typedef ``['-unspecified-]`` left_map;
typedef ``['-unspecified-]`` right_tag;
typedef ``['-unspecified-]`` right_value_type;
typedef ``['-unspecified-]`` right_key_type;
typedef ``['-unspecified-]`` right_data_type;
typedef ``['-unspecified-]`` right_iterator;
typedef ``['-unspecified-]`` right_const_iterator;
typedef ``['-unspecified-]`` right_map;
// Map views
left_map left;
right_map right;
// Constructors
bimap();
template< class InputIterator >
bimap(InputIterator first,InputIterator last);
bimap(const bimap &);
bimap& operator=(const bimap& b);
// Projection of iterators
template< class IteratorType >
left_iterator project_left(IteratorType iter);
template< class IteratorType >
left_const_iterator project_left(IteratorType iter) const;
template< class IteratorType >
right_iterator project_right(IteratorType iter);
template< class IteratorType >
right_const_iterator project_right(IteratorType iter) const;
template< class IteratorType >
iterator project_up(IteratorType iter);
template< class IteratorType >
const_iterator project_up(IteratorType iter) const;
// Support for tags
template< class Tag >
struct map_by;
template< class Tag >
map_by<Tag>::type by();
template< class Tag >
const map_by<Tag>::type & by() const;
template< class Tag, class IteratorType >
map_by<Tag>::iterator project(IteratorType iter);
template< class Tag, class IteratorType >
map_by<Tag>::const_iterator project(IteratorType iter) const
};
} // namespace bimap
} // namespace boost
[/
// Metafunctions for a bimap
template< class Tag, class Bimap > struct value_type_by;
template< class Tag, class Bimap > struct key_type_by;
template< class Tag, class Bimap > struct data_type_by;
template< class Tag, class Bimap > struct iterator_type_by;
template< class Tag, class Bimap > struct const_iterator_type_by;
template< class Tag, class Bimap > struct reverse_iterator_type_by;
template< class Tag, class Bimap > struct const_reverse_iterator_type_by;
template< class Tag, class Bimap > struct local_iterator_type_by;
template< class Tag, class Bimap > struct const_local_iterator_type_by;
// Functions for a bimap
template<class Tag, class Relation>
result_of::map_by< Tag, Bimap>::type map_by(Bimap &);
// Metafunctions for a relation
template< class Tag, class Relation > struct value_type_of;
template< class Tag, class Relation > struct pair_type_by;
// Functions for a relation
template<class Tag, class Relation>
result_of::get< Tag, Relation>::type get(Relation &r);
template<class Tag, class Relation>
result_of::pair_by< Tag, Relation>::type pair_by(Relation &);
]
[endsect]
[section Class template bimap]
This is the main component of Boost.Bimap.
[section Complexity]
In the descriptions of the operations of `bimap`, we adopt the scheme
outlined in the complexity signature section.
[endsect]
[section Instantiation types]
`bimap` is instantiated with the following types:
# LeftCollectionType and RightCollectionType are collection type specifications
optionally tagged, or any type optionally tagged, in which case that
side acts as a set.
# AdditionalParameter_{1/2} can be any ordered subset of:
* CollectionTypeOfRelation specification
* Allocator
[endsect]
[section Nested types]
left_tag, right_tag
[: Tags for each side of the bimap. If the user has not specified any tag the
tags default to `member_at::left` and `member_at::right`.
]
left_key_type, right_key_type
[: Key type of each side. In a `bimap<A,B> ` `left_key_type` is `A` and
`right_key_type` is `B`.
If there are tags, it is better to use: `Bimap::map_by<Tag>::key_type`.
]
left_data_type, right_data_type
[: Data type of each side. In a bimap<A,B> left_key_type is B and
right_key_type is A.
If there are tags, it is better to use: `Bimap::map_by<Tag>::data_type`.
]
left_value_type, right_value_type
[: Value type used for the views.
If there are tags, it is better to use: `Bimap::map_by<Tag>::value_type`.
]
left_iterator, right_iterator
left_const_iterator, right_const_iterator
[: Iterators of the views.
If there are tags, it is better to use:
`Bimap::map_by<Tag>::iterator` and
`Bimap::map_by<Tag>::const_iterator`
]
left_map, right_map
[: Map view type of each side.
If there are tags, it is better to use:
`Bimap::map_by<Tag>::type`.
]
[endsect]
[section Constructors, copy and assignment]
bimap();
* [*Effects:] Constructs an empty `bimap`.
* [*Complexity:] Constant.
template<typename InputIterator>
bimap(InputIterator first,InputIterator last);
* [*Requires: ] `InputIterator` is a model of Input Iterator over elements of
type `relation` or a type convertible to `relation`. last is reachable from `first`.
* [*Effects:] Constructs an empty `bimap` and fills it with the elements in the range
`[first,last)`. Insertion of each element may or may not succeed depending on
acceptance by the collection types of the `bimap`.
* [link complexity_signature_explanation
[*Complexity:]] O(m*H(m)), where m is the number of elements in `[first,last)`.
bimap(const bimap & x);
* [*Effects:] Constructs a copy of x, copying its elements as well as its
internal objects (key extractors, comparison objects, allocator.)
* [*Postconditions:] `*this == x`. The order of the views of the `bimap`
is preserved as well.
* [*Complexity:] O(x.size()*log(x.size()) + C(x.size()))
~bimap()
* [*Effects:] Destroys the `bimap` and all the elements contained.
The order in which the elements are destroyed is not specified.
* [*Complexity:] O(n).
bimap& operator=(const bimap& x);
* [*Effects:] Replaces the elements and internal objects of the `bimap`
with copies from x.
* [*Postconditions:] `*this==x`. The order on the views of the `bimap`
is preserved as well.
* [*Returns: ] `*this`.
* [*Complexity:] O(n + x.size()*log(x.size()) + C(x.size())).
* [*Exception safety:] Strong, provided the copy and assignment operations
of the types of `ctor_args_list` do not throw.
[/
allocator_type get_allocator() const;
* [*Effects:] Returns a copy of the `allocator_type` object used to construct
the `bimap`.
* [*Complexity:] Constant.
]
[endsect]
[#reference_projection_operations]
[section Projection operations]
Given a `bimap` with views v1 and v2, we say than an v1-iterator
it1 and an v2-iterator it2 are equivalent if:
* `it1 == i1.end()` AND `it2 == i2.end()`,
* OR `it1` and `it2` point to the same element.
template< class IteratorType >
left_iterator project_left(IteratorType iter);
template< class IteratorType >
left_const_iterator project_left(IteratorType iter) const;
* [*Requires:] `IteratorType` is a bimap view iterator. it is a
valid iterator of some view of `*this` (i.e. does not refer to some other
`bimap`.)
* [*Effects:] Returns a left map view iterator equivalent to `it`.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
template< class IteratorType >
right_iterator project_right(IteratorType iter);
template< class IteratorType >
right_const_iterator project_right(IteratorType iter) const;
* [*Requires:] `IteratorType` is a bimap view iterator. it is a
valid iterator of some view of `*this` (i.e. does not refer to some other
`bimap`.)
* [*Effects:] Returns a right map view iterator equivalent to `it`.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
template< class IteratorType >
iterator project_up(IteratorType iter);
template< class IteratorType >
const_iterator project_up(IteratorType iter) const;
* [*Requires:] `IteratorType` is a bimap view iterator. it is a
valid iterator of some view of `*this` (i.e. does not refer to some other
`bimap`.)
* [*Effects:] Returns a collection of relations view iterator equivalent to `it`.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[endsect]
[#reference_support_for_used_defined_names]
[section Support for user defined names]
template< class Tag >
struct map_by;
* `map_by<Tag>::type` yields the type of the map view tagged with `Tag`.
`map_by<Tag>::`['-type name-] is the same as `map_by<Tag>::type::`['-type name-].
* [*Requires: ] `Tag` is a valid user defined name of the bimap.
template< class Tag >
map_by<Tag>::type by();
template< class Tag >
const map_by<Tag>::type & by() const;
* [*Requires: ] `Tag` is a valid user defined name of the bimap.
* [*Effects:] Returns a reference to the map view tagged with `Tag` held by
`*this`.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
template< class Tag, class IteratorType >
map_by<Tag>::iterator project(IteratorType iter);
template< class Tag, class IteratorType >
map_by<Tag>::const_iterator project(IteratorType iter) const
* [*Requires: ] `Tag` is a valid user defined name of the bimap. `IteratorType`
is a bimap view iterator. it is a valid iterator of some view of `*this`
(i.e. does not refer to some other `bimap`.)
* [*Effects:] Returns a reference to the map view tagged with `Tag` held by
`*this`.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[endsect]
[section Serialization]
A `bimap` can be archived and retrieved by means of __BOOST_SERIALIZATION__.
Boost.Bimap does not expose a public serialisation interface, as this is
provided by Boost.Serialization itself. Both regular and XML archives
are supported.
Each of the set specifications comprising a given `bimap` contributes its
own preconditions as well as guarantees on the retrieved containers. In describing
these, the following concepts are used. A type `T` is ['serializable]
(resp. XML-serializable) if any object of type `T` can be saved to an output
archive (XML archive) and later retrieved from an input archive (XML archive)
associated to the same storage. If `x`' of type `T` is loaded from the serialization
information saved from another object x, we say that x' is a ['restored copy] of x.
Given a __SGI_BINARY_PREDICATE__ `Pred` over `(T, T)`, and objects `p` and `q` of
type `Pred`, we say that `q` is ['serialization-compatible] with `p` if
* `p(x,y) == q(x`'`,y`'`)`
for every `x` and `y` of type `T` and `x`' and `y`' being restored copies of `x`
and `y`, respectively.
[blurb [*Operation:] saving of a `bimap b` to an output archive
(XML archive) ar.]
* [*Requires:] Value is serializable (XML-serializable). Additionally, each
of the views of b can impose other requirements.
* [*Exception safety:] Strong with respect to `b`. If an exception is thrown, ar
may be left in an inconsistent state.
[blurb [*Operation:] loading of a `bimap` m' from an input archive
(XML archive) ar.]
* [*Requires:] Value is serializable (XML-serializable). Additionally, each of
the views of `b`' can impose other requirements.
* [*Exception safety:] Basic. If an exception is thrown, ar may be left in an
inconsistent state.
[endsect]
[endsect]
[endsect]

796
doc/reference/list_of.qbk Executable file
View File

@@ -0,0 +1,796 @@
[/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;
// construct/copy/destroy
this_type & operator=(const this_type & x);
template< class InputIterator >
void ``[link reference_list_of_assign_iterator_iterator assign]``(InputIterator first, InputIterator last);
void ``[link reference_list_of_assign_size_value assign]``(size_type n, const value_type & value);
allocator_type get_allocator() const;
// iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
// capacity
bool empty() const;
size_type size() const;
size_type max_size() const;
void ``[link reference_list_of_resize_size_value resize]``(size_type n, const value_type & x = value_type());
// access
const_reference front() const;
const_reference back() const;
// modifiers
std::pair<iterator,bool> ``[link reference_list_of_push_front_value push_front]``(const value_type & x);
void pop_front();
std::pair<iterator,bool> ``[link reference_list_of_push_back_value push_back]``(const value_type & x);
void pop_back();
std::pair<iterator,bool> ``[link reference_list_of_insert_iterator_value insert]``(iterator position, const value_type & x);
void ``[link reference_list_of_insert_iterator_size_value insert]``(iterator position, size_type n, const value_type & x);
template< class InputIterator >
void ``[link reference_list_of_insert_iterator_iterator_iterator insert]``(iterator position, InputIterator first, InputIterator last);
iterator ``[link reference_list_of_erase_iterator erase]``(iterator position);
iterator ``[link reference_list_of_erase_iterator_iterator erase]``(iterator first, iterator last);
bool ``[link reference_list_of_replace_iterator_value replace]``(iterator position, const value_type & x);
// Only in map views
// {
template< class CompatibleKey >
bool ``[link reference_list_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
template< class CompatibleData >
bool ``[link reference_list_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
template< class KeyModifier >
bool ``[link reference_list_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
template< class DataModifier >
bool ``[link reference_list_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
// }
void clear();
// list operations
void ``[link reference_list_of_splice_iterator_this splice]``(iterator position, this_type & x);
void ``[link reference_list_of_splice_iterator_this_iterator splice]``(iterator position, this_type & x, iterator i);
void splice(
iterator position, this_type & x, iterator first, iterator last);
void ``[link reference_list_of_remove_value remove]``(const value_type & value);
template< class Predicate >
void ``[link reference_list_of_remove_if_predicate remove_if]``(Predicate pred);
void ``[link reference_list_of_unique unique]``();
template< class BinaryPredicate >
void ``[link reference_list_of_unique_predicate unique]``(BinaryPredicate binary_pred);
void ``[link reference_list_of_merge_this merge]``(this_type & x);
template< class Compare >
void ``[link reference_list_of_merge_this_compare merge]``(this_type & x,Compare comp);
void ``[link reference_list_of_sort sort]``();
template< class Compare >
void ``[link reference_list_of_sort_compare sort]``(Compare comp);
void ``[link reference_list_of_reverse reverse]``();
// rearrange operations
void relocate(iterator position, iterator i);
void relocate(iterator position, iterator first, iterator last);
}
// view comparison
bool operator==(const this_type & v1, const this_type & v2 );
bool operator< (const this_type & v1, const this_type & v2 );
bool operator!=(const this_type & v1, const this_type & v2 );
bool operator> (const this_type & v1, const this_type & v2 );
bool operator>=(const this_type & v1, const this_type & v2 );
bool operator<=(const this_type & v1, const this_type & v2 );
} // namespace views
} // namespace bimap
} // namespace boost
In the case of a `bimap< list_of<Left>, ... >`
In the set view:
typedef signature-compatible with relation< Left, ... > key_type;
typedef signature-compatible with relation< Left, ... > value_type;
In the left map view:
typedef Left key_type;
typedef ... data_type;
typedef signature-compatible with std::pair< Left, ... > value_type;
In the right map view:
typedef ... key_type;
typedef Left data_type;
typedef signature-compatible with std::pair< ... , Left > value_type;
[#list_of_complexity_signature]
[section Complexity signature]
Here and in the descriptions of operations of `list_of` views, we adopt the
scheme outlined in the
[link complexity_signature_explanation complexity signature section].
The complexity signature of a `list_of` view is:
* copying: `c(n) = n * log(n)`,
* insertion: `i(n) = 1` (constant),
* hinted insertion: `h(n) = 1` (constant),
* deletion: `d(n) = 1` (constant),
* replacement: `r(n) = 1` (constant),
* modifying: `m(n) = 1` (constant).
[endsect]
[section Instantiation types]
`list_of` views are instantiated internally to `bimap` and specified
by means of the collection type specifiers and the bimap itself.
Instantiations are dependent on the following types:
* `Value` from `list_of`,
* `Allocator` from `bimap`,
[endsect]
[section Constructors, copy and assignment]
As explained in the view concepts section, views do not have public
constructors or destructors. Assignment, on the other hand, is provided.
this_type & operator=(const this_type & x);
* [*Effects: ] `a = b;`
where a and b are the `bimap` objects to which `*this` and `x` belong,
respectively.
* [*Returns: ] `*this`.
[#reference_list_of_assign_iterator_iterator]
template< class InputIterator >
void assign(InputIterator first, InputIterator last);
* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of type
`value_type` or a type convertible to `value_type`. first and last are not
iterators into any views of the `bimap` to which this view belongs.
`last` is reachable from `first`.
* [*Effects: ] `clear(); insert(end(),first,last);`
[#reference_list_of_assign_size_value]
void assign(size_type n, const value_type & value);
* [*Effects: ] `clear(); for(size_type i = 0; i < n ; ++n) push_back(v);`
[endsect]
[section Capacity operations]
[#reference_list_of_resize_size_value]
void resize(size_type n,const value_type& x=value_type());
* [*Effects: ]
`if( n > size() ) insert(end(), n - size(), x);`
`else if( n < size() ) {`
` iterator it = begin();`
` std::advance(it, n);`
` erase(it, end());`
`}`
* [*Note:] If an expansion is requested, the size of the view is not
guaranteed to be n after this operation (other views may ban insertions.)
[endsect]
[section Modifiers]
[#reference_list_of_push_front_value]
std::pair<iterator,bool> push_front(const value_type& x);
* [*Effects:] Inserts `x` at the beginning of the sequence if no other views
of the `bimap` bans the insertion.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only
if insertion took place. On successful insertion, `p.first` points to the element
inserted; otherwise, `p.first` points to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be allowed.
* [link list_of_complexity_signature [*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_list_of_push_back_value]
std::pair<iterator,bool> push_back(const value_type & x);
* [*Effects:] Inserts `x` at the end of the sequence if no other views of the
`bimap` bans the insertion.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if
insertion took place. On successful insertion, `p.first` points to the element
inserted; otherwise, `p.first` points to an element that caused the insertion
to be banned. Note that more than one element can be causing insertion not
to be allowed.
* [link list_of_complexity_signature [*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_list_of_insert_iterator_value]
std::pair<iterator,bool> insert(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid `iterator` of the view.
* [*Effects:] Inserts `x` before position if insertion is allowed by all other
views of the `bimap`.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if
insertion took place. On successful insertion, `p.first` points to the element
inserted; otherwise, `p.first` points to an element that caused the insertion
to be banned. Note that more than one element can be causing insertion not
to be allowed.
* [link list_of_complexity_signature
[*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_list_of_insert_iterator_size_value]
void insert(iterator position, size_type n, const value_type & x);
* [*Requires: ] `position` is a valid `iterator` of the view.
* [*Effects: ] `for(size_type i = 0; i < n; ++i) insert(position, x);`
[#reference_list_of_insert_iterator_iterator_iterator]
template< class InputIterator>
void insert(iterator position,InputIterator first,InputIterator last);
* [*Requires: ] `position` is a valid `iterator` of the view. `InputIterator` is
a model of __SGI_INPUT_ITERATOR__ over elements of type `value_type`.
`first` and `last` are not iterators into any view of the
`bimap` to which this view belongs. `last` is reachable from `first`.
* [*Effects: ] `while(first != last) insert(position, *first++);`
* [link list_of_complexity_signature
[*Complexity:]] O(m*I(n+m)), where m is the number of elements in `[first,last)`.
* [*Exception safety:] Basic.
[#reference_list_of_erase_iterator]
iterator erase(iterator position);
* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view.
* [*Effects:] Deletes the element pointed to by `position`.
* [*Returns:] An iterator pointing to the element immediately following the
one that was deleted, or `end()` if no such element exists.
* [link list_of_complexity_signature
[*Complexity:]] O(D(n)).
* [*Exception safety:] nothrow.
[#reference_list_of_erase_iterator_iterator]
iterator erase(iterator first, iterator last);
* [*Requires: ] `[first,last)` is a valid range of the view.
* [*Effects:] Deletes the elements in `[first,last)`.
* [*Returns: ] `last`.
* [link list_of_complexity_signature
[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
* [*Exception safety:] nothrow.
[#reference_list_of_replace_iterator_value]
bool replace(iterator position,const value_type& x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
the `bimap` to which the view belongs if replacing is allowed by
all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation the `bimap` to which the view belongs remains in its
original state.
[#reference_list_of_replace_key_iterator_key]
template< class CompatibleKey >
bool replace_key(iterator position, const CompatibleKey & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `key_type`.
* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_list_of_replace_data_iterator_data]
template< class CompatibleData >
bool replace_data(iterator position, const CompatibleData & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `data_type`.
* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_list_of_modify_key_iterator_modifier]
template< class KeyModifier >
bool modify_key(iterator position, KeyModifier mod);
* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `key_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
It is successful if the rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[#reference_list_of_modify_data_iterator_modifier]
template< class DataModifier >
bool modify_data(iterator position, DataModifier mod);
* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `data_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
It is successful if the rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[/
[#reference_list_of_modify_iterator_modifier]
template< class Modifier >
bool modify(iterator position,Modifier mod);
* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of
type: `first_type&` and `second_type&` for ['Map View] and `left_type&` and `right_type&`
for ['Set View]. `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View] or calls `mod(e.left,e.right)`
for ['Set View] where `e` is the element pointed to by `position` and
rearranges `*position` into all the views of the `bimap`.
Rearrangement on `list_of` views does not change the position of the element
with respect to the view; rearrangement on other views may or might not suceed.
If the rearrangement fails, the element is erased.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link list_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly `mod`), then the element pointed to by position is erased.
]
[endsect]
[section List operations]
`list_of` views provide the full set of list operations found in `std::list`;
the semantics of these member functions, however, differ from that of `std::list`
in some cases as insertions might not succeed due to banning by other views.
Similarly, the complexity of the operations may depend on the other views
belonging to the same `bimap`.
[#reference_list_of_splice_iterator_this]
void splice(iterator position, this_type & x);
* [*Requires: ] `position` is a valid iterator of the view. `&x!=this`.
* [*Effects:] Inserts the contents of `x` before position, in the same order as
they were in `x`. Those elements successfully inserted are erased from `x`.
* [link list_of_complexity_signature
[*Complexity:]] O(`x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
* [*Exception safety:] Basic.
[#reference_list_of_splice_iterator_this_iterator]
void splice(iterator position, this_type & x,iterator i);
* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
dereferenceable iterator `x`.
* [*Effects:] Inserts the element pointed to by `i` before position: if insertion
is successful, the element is erased from `x`. In the special case `&x==this`,
no copy or deletion is performed, and the operation is always successful. If
`position==i`, no operation is performed.
* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
* [link list_of_complexity_signature
[*Complexity:]] If `&x==this`, constant; otherwise O(I(n) + D(n)).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, strong.
[#reference_list_of_splice_iterator_this_iterator_iterator]
void splice(iterator position, this_type & x, iterator first, iterator last);
* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are
valid iterators of `x`. last is reachable from `first`. position is not in the
range `[first,last)`.
* [*Effects:] For each element in the range `[first,last)`, insertion is tried
before position; if the operation is successful, the element is erased from x.
In the special case `&x==this`, no copy or deletion is performed, and insertions
are always successful.
* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
* [link list_of_complexity_signature
[*Complexity:]] If `&x==this`, constant; otherwise O(m*I(n+m) + m*D(x.size()))
where m is the number of elements in `[first,last)`.
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_list_of_remove_value]
void remove(const value_type & value);
* [*Effects:] Erases all elements of the view which compare equal to `value`.
* [link list_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_list_of_remove_if_predicate]
template< class Predicate >
void remove_if(Predicate pred);
* [*Effects:] Erases all elements `x` of the view for which `pred(x)` holds.
* [link list_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_list_of_unique]
void unique();
* [*Effects:] Eliminates all but the first element from every consecutive
group of equal elements referred to by the iterator `i` in the range
`[first+1,last)` for which `*i==*(i-1)`.
* [link list_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_list_of_unique_predicate]
template< class BinaryPredicate >
void unique(BinaryPredicate binary_pred);
* [*Effects:] Eliminates all but the first element from every consecutive
group of elements referred to by the iterator i in the range \[first+1,last)
for which `binary_pred(*i,*(i-1))` holds.
* [link list_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_list_of_merge_this]
void merge(this_type & x);
* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
Both the view and `x` are sorted according to `std::less<value_type>`.
* [*Effects:] Attempts to insert every element of `x` into the corresponding
position of the view (according to the order). Elements successfully inserted
are erased from `x`. The resulting sequence is stable, i.e. equivalent elements
of either container preserve their relative position. In the special case
`&x==this`, no operation is performed.
* [*Postconditions:] Elements in the view and remaining elements in `x` are sorted.
Validity of iterators to the view and of non-erased elements of `x` references
is preserved.
* [link list_of_complexity_signature
[*Complexity:]] If `&x==this`, constant; otherwise
O(n + `x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_list_of_merge_this_compare]
template< class Compare >
void merge(this_type & x, Compare comp);
* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`. Both the view
and `x` are sorted according to `comp`.
* [*Effects:] Attempts to insert every element of `x` into the corresponding position
of the view (according to `comp`). Elements successfully inserted are erased from `x`.
The resulting sequence is stable, i.e. equivalent elements of either container preserve
their relative position. In the special case `&x==this`, no operation is performed.
* [*Postconditions:] Elements in the view and remaining elements in `x` are sorted
according to `comp`. Validity of iterators to the view and of non-erased elements
of `x` references is preserved.
* [link list_of_complexity_signature
[*Complexity:]] If `&x==this`, constant;
otherwise O(n + `x.size()`*I(n+`x.size()`) + `x.size()`*D(`x.size()`)).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_list_of_sort]
void sort();
* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over value_type.
* [*Effects:] Sorts the view according to `std::less<value_type>`. The sorting is stable,
i.e. equivalent elements preserve their relative position.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n*log(n)).
* [*Exception safety:] nothrow if `std::less<value_type>` does not throw; otherwise, basic.
[#reference_list_of_sort_compare]
template< typename Compare >
void sort(Compare comp);
* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over value_type.
* [*Effects:] Sorts the view according to comp. The sorting is stable, i.e. equivalent
elements preserve their relative position.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n*log(n)).
* [*Exception safety:] nothrow if comp does not throw; otherwise, basic.
[#reference_list_of_reverse]
void reverse();
* [*Effects:] Reverses the order of the elements in the view.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n).
* [*Exception safety:] nothrow.
[endsect]
[section Rearrange operations]
These operations, without counterpart in `std::list` (although splice provides
partially overlapping functionality), perform individual and global repositioning
of elements inside the index.
[#reference_list_of_relocate_iterator_iterator]
void relocate(iterator position, iterator i);
* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
dereferenceable iterator of the view.
* [*Effects:] Inserts the element pointed to by `i` before `position`.
If `position==i`, no operation is performed.
* [*Postconditions:] No iterator or reference is invalidated.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[#reference_list_of_relocate_iterator_iterator_iterator]
void relocate(iterator position, iterator first, iterator last);
* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are
valid iterators of the view. `last` is reachable from `first`. `position` is not
in the range `[first,last)`.
* [*Effects:] The range of elements `[first,last)` is repositioned just before
`position`.
* [*Postconditions:] No iterator or reference is invalidated.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[endsect]
[section Serialization]
Views cannot be serialized on their own, but only as part of the
`bimap` into which they are embedded. In describing the additional
preconditions and guarantees associated to `list_of` views with respect to
serialization of their embedding containers, we use the concepts defined in the
`bimap` serialization section.
[blurb [*Operation:] saving of a `bimap` b to an output archive
(XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[blurb [*Operation:] loading of a `bimap` b' from an input archive
(XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[*Postconditions:] On successful loading, each of the elements of
`[begin(), end())`
is a restored copy of the corresponding element in
`[m.get<i>().begin(), m.get<i>().end())`,
where `i` is the position of the `list_of` view in the container.
[blurb [*Operation:] saving of an `iterator` or `const_iterator` it to an output
archive (XML archive) ar.]
* [*Requires: ] `it` is a valid iterator of the view. The associated
`bimap` has been previously saved.
[blurb [*Operation:] loading of an `iterator` or `const_iterator it`' from an input
archive (XML archive) ar.]
* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
restored copy of `*it`, otherwise `it`'` == end()`.
* [*Note:] It is allowed that `it` be a `const_iterator` and the restored `it`' an iterator,
or viceversa.
[endsect]
[endsect]
[endsect]

906
doc/reference/set_of.qbk Executable file
View File

@@ -0,0 +1,906 @@
[/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;
this_type & operator=(const this_type & x);
allocator_type get_allocator() const;
// iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
// capacity
bool empty() const;
size_type size() const;
size_type max_size() const;
// modifiers
std::pair<iterator,bool> ``[link reference_set_of_insert_value insert]``(const value_type & x);
iterator ``[link reference_set_of_insert_iterator_value insert]``(iterator position, const value_type & x);
template< class InputIterator>
void ``[link reference_set_of_insert_iterator_iterator insert]``(InputIterator first, InputIterator last);
iterator ``[link reference_set_of_erase_iterator erase]``(iterator position);
template< class CompatibleKey >
size_type ``[link reference_set_of_erase_key erase]``(const CompatibleKey & x);
iterator ``[link reference_set_of_erase_iterator_iterator erase]``(iterator first, iterator last);
bool ``[link reference_set_of_replace_iterator_value replace]``(iterator position, const value_type& x);
// Only in map views
// {
template< class CompatibleKey >
bool ``[link reference_set_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
template< class CompatibleData >
bool ``[link reference_set_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
template< class KeyModifier >
bool ``[link reference_set_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
template< class DataModifier >
bool ``[link reference_set_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
// }
void swap(this_type & x);
void clear();
// observers
key_compare key_comp() const;
value_compare value_comp() const;
// set operations
template< class CompatibleKey >
iterator ``[link reference_set_of_find_key find]``(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator ``[link reference_set_of_find_key find]``(const CompatibleKey & x) const;
template< class CompatibleKey >
size_type ``[link reference_set_of_count_key count]``(const CompatibleKey & x) const;
template< class CompatibleKey >
iterator ``[link reference_set_of_lower_bound_key lower_bound]``(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator ``[link reference_set_of_lower_bound_key lower_bound]``(const CompatibleKey & x) const;
template< class CompatibleKey >
iterator ``[link reference_set_of_upper_bound_key upper_bound]``(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator ``[link reference_set_of_upper_bound_key upper_bound]``(const CompatibleKey & x) const;
template< class CompatibleKey >
std::pair<iterator,iterator>
``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x);
template< class CompatibleKey >
std::pair<const_iterator,const_iterator>
``[link reference_set_of_equal_range_key equal_range]``(const CompatibleKey & x) const;
// Only in maps views
// {
template< class LowerBounder, class UpperBounder>
std::pair<iterator,iterator> ``[link reference_set_of_range_lower_upper range]``(
LowerBounder lower, UpperBounder upper);
template< class LowerBounder, class UpperBounder>
std::pair<const_iterator,const_iterator> ``[link reference_set_of_range_lower_upper range]``(
LowerBounder lower, UpperBounder upper) const;
typedef ``['-unspecified-]`` data_type;
// Only in for `set_of` collection type
// {
template< class CompatibleKey >
const data_type & ``[link reference_set_of_at_key_const at]``(const CompatibleKey & k) const;
// Only if the other collection type is mutable
// {
template< class CompatibleKey >
data_type & ``[link reference_set_of_operator_bracket_key operator\[\]]``(const CompatibleKey & k);
template< class CompatibleKey >
data_type & ``[link reference_set_of_at_key at]``(const CompatibleKey & k);
// }
// }
// }
};
// view comparison
bool operator==(const this_type & v1, const this_type & v2 );
bool operator< (const this_type & v1, const this_type & v2 );
bool operator!=(const this_type & v1, const this_type & v2 );
bool operator> (const this_type & v1, const this_type & v2 );
bool operator>=(const this_type & v1, const this_type & v2 );
bool operator<=(const this_type & v1, const this_type & v2 );
} // namespace views
} // namespace bimap
} // namespace boost
[/ Functions that may be implemented some day
template< class Modifier>
bool ``[link reference_set_of_modify_iterator_modifier modify]``(iterator position, Modifier mod);
template< class CompatibleKey, class CompatibleCompare >
iterator find(const CompatibleKey & x,
const CompatibleCompare & comp);
template< class CompatibleKey, class CompatibleCompare >
const_iterator find(const CompatibleKey & x,
const CompatibleCompare & comp) const;
template< class CompatibleKey, class CompatibleCompare >
size_type count(const CompatibleKey & x,
const CompatibleCompare & comp) const;
template< class CompatibleKey, class CompatibleCompare >
iterator lower_bound(const CompatibleKey & x,
const CompatibleCompare & comp);
template< class CompatibleKey, class CompatibleCompare >
const_iterator lower_bound(const CompatibleKey & x,
const CompatibleCompare & comp) const;
template< class CompatibleKey, class CompatibleCompare >
iterator upper_bound(const CompatibleKey & x,
const CompatibleCompare & comp);
template< class CompatibleKey, class CompatibleCompare >
const_iterator upper_bound(const CompatibleKey & x,
const CompatibleCompare & comp) const;
template< class CompatibleKey, class CompatibleCompare >
std::pair<iterator,iterator> equal_range(
const CompatibleKey & x, const CompatibleCompare & comp);
template< class CompatibleKey, class CompatibleCompare >
std::pair<const_iterator,const_iterator> equal_range(
const CompatibleKey & x, const CompatibleCompare & comp) const;
]
In the case of a `bimap< {multi}set_of<Left>, ... >`
In the set view:
typedef signature-compatible with relation< Left, ... > key_type;
typedef signature-compatible with relation< const Left, ... > value_type;
In the left map view:
typedef Left key_type;
typedef ... data_type;
typedef signature-compatible with std::pair< const Left, ... > value_type;
In the right map view:
typedef ... key_type;
typedef Left data_type;
typedef signature-compatible with std::pair< ... ,const Left > value_type;
[#set_of_complexity_signature]
[section Complexity signature]
Here and in the descriptions of operations of this view, we adopt the
scheme outlined in the [link complexity_signature_explanation complexity signature section].
The complexity signature of \[multi\]set_of view is:
* copying: `c(n) = n * log(n)`,
* insertion: `i(n) = log(n)`,
* hinted insertion: `h(n) = 1` (constant) if the hint element precedes the point of
insertion, `h(n) = log(n)` otherwise,
* deletion: `d(n) = 1` (amortized constant),
* replacement: `r(n) = 1` (constant) if the element position does not change,
`r(n) = log(n)` otherwise,
* modifying: `m(n) = 1` (constant) if the element position does not change,
`m(n) = log(n)` otherwise.
[endsect]
[section Instantiation types]
Set views are instantiated internally to a `bimap`.
Instantiations are dependent on the following types:
* `Value` from the set specifier,
* `Allocator` from `bimap`,
* `Compare` from the set specifier.
`Compare` is a __SGI_STRICT_WEAK_ORDERING__ on elements of `Value`.
[endsect]
[section Constructors, copy and assignment]
Set views do not have public constructors or destructors.
Assignment, on the other hand, is provided.
this_type & operator=(const this_type & x);
* [*Effects: ] `a = b;`
where a and b are the `bimap` objects to which `*this` and x
belong, respectively.
* [*Returns: ] `*this`.
[endsect]
[section Modifiers]
[#reference_set_of_insert_value]
std::pair<iterator,bool> insert(const value_type & x);
* [*Effects:] Inserts `x` into the `bimap` to which the set view belongs if
* the set view is non-unique OR no other element with equivalent key exists,
* AND insertion is allowed by the other set specifications the `bimap`.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if insertion
took place. On successful insertion, `p.first` points to the element inserted;
otherwise, `p.first` points to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.
* [link set_of_complexity_signature
[*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_set_of_insert_iterator_value]
iterator insert(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid iterator of the view.
* [*Effects: ] `position` is used as a hint to improve the efficiency of the operation. Inserts `x` into the `bimap` to which the view belongs if
* the set view is non-unique OR no other element with equivalent key exists,
* AND insertion is allowed by all other views of the `bimap`.
* [*Returns:] On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator to an element that caused the insertion to be
banned. Note that more than one element can be causing insertion not to be allowed.
* [link set_of_complexity_signature
[*Complexity:]] O(H(n)).
* [*Exception safety:] Strong.
[#reference_set_of_insert_iterator_iterator]
template< class InputIterator >
void insert(InputIterator first, InputIterator last);
* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of
type `value_type` or a type convertible to value_type. `first` and `last` are not
iterators into any view of the `bimap` to which this index
belongs. `last` is reachable from `first`.
* [*Effects: ]
`iterator hint = end()`;
`while( first != last ) hint = insert( hint, *first++ );`
* [link set_of_complexity_signature
[*Complexity:]] O(m*H(n+m)), where m is the number of elements in
`[first, last)`.
* [*Exception safety:] Basic.
[#reference_set_of_erase_iterator]
iterator erase(iterator position);
* [*Requires: ] `position` is a valid dereferenceable iterator if the set view.
* [*Effects:] Deletes the element pointed to by `position`.
* [*Returns:] An iterator pointing to the element immediately following
the one that was deleted, or `end()` if no such element exists.
* [link set_of_complexity_signature
[*Complexity:]] O(D(n)).
* [*Exception safety:] nothrow.
[#reference_set_of_erase_key]
template< class CompatibleKey >
size_type erase(const CompatibleKey & x);
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Deletes the elements with key equivalent to `x`.
* [*Returns:] Number of elements deleted.
* [link set_of_complexity_signature
[*Complexity:]] O(log(n) + m*D(n)), where m is the number of elements deleted.
* [*Exception safety:] Basic.
[#reference_set_of_erase_iterator_iterator]
iterator erase(iterator first, iterator last);
* [*Requires: ] `[first,last)` is a valid range of the view.
* [*Effects:] Deletes the elements in `[first,last)`.
* [*Returns:] last.
* [link set_of_complexity_signature
[*Complexity:]] O(log(n) + m*D(n)), where m is the number of elements
in `[first,last)`.
* [*Exception safety:] nothrow.
[#reference_set_of_replace_iterator_value]
bool replace(iterator position, const value_type& x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
the `bimap` to which the set view belongs if, for the value `x`
* the set view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_set_of_replace_key_iterator_key]
template< class CompatibleKey >
bool replace_key(iterator position, const CompatibleKey & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `key_type`.
* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if,
* the map view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_set_of_replace_data_iterator_data]
template< class CompatibleData >
bool replace_data(iterator position, const CompatibleData & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `data_type`.
* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if,
* the map view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_set_of_modify_key_iterator_modifier]
template< class KeyModifier >
bool modify_key(iterator position, KeyModifier mod);
* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `key_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the map view is non-unique OR no other element with equivalent key exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[#reference_set_of_modify_data_iterator_modifier]
template< class DataModifier >
bool modify_data(iterator position, DataModifier mod);
* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `data_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the oppositte map view is non-unique OR no other element with equivalent key in that
view exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[/
[#reference_set_of_modify_iterator_modifier]
template< class Modifier >
bool modify(iterator position, Modifier mod);
* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of
type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&`
['Set View]; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View] or Calls `mod(e.left,e.right)`
for ['Set View] where e is the element pointed to by position and rearranges `*position`
into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the view is non-unique OR no other element with equivalent key exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
]
[endsect]
[section Set operations]
`[multi]set_of` views provide the full lookup functionality required by
__SGI_SORTED_ASSOCIATIVE_CONTAINER__ and __SGI_UNIQUE_ASSOCIATIVE_CONTAINER__,
namely `find`, `count`, `lower_bound`, `upper_bound` and `equal_range`.
Additionally, these member functions are templatized to allow for non-standard
arguments, so extending the types of search operations allowed.
[/
The kinds of arguments permissible when invoking the lookup member functions
are defined by the following concept.
Consider a __SGI_STRICT_WEAK_ORDERING__ `Compare` over values of type `Key`. A pair of
types `(CompatibleKey, CompatibleCompare)` is said to be a ['compatible extension]
of Compare if
* `CompatibleCompare` is a __SGI_BINARY_PREDICATE__ over `(Key, CompatibleKey)`,
* `CompatibleCompare` is a __SGI_BINARY_PREDICATE__ over `(CompatibleKey, Key)`,
* if `c_comp(ck,k1)` then `!c_comp(k1,ck)`,
* if `!c_comp(ck,k1)` and `!comp(k1,k2)` then `!c_comp(ck,k2)`,
* if `!c_comp(k1,ck)` and `!comp(k2,k1)` then `!c_comp(k2,ck)`,
for every `c_comp` of type `CompatibleCompare`, `comp` of type `Compare`, `ck` of type
`CompatibleKey` and `k1`, `k2` of type `Key`.
]
A type `CompatibleKey` is said to be a ['compatible key] of `Compare`
if `(CompatibleKey, Compare)` is a compatible extension of `Compare`. This implies
that `Compare`, as well as being a strict weak ordering, accepts arguments of type
`CompatibleKey`, which usually means it has several overloads of `operator()`.
[/
In the context of a compatible extension or a compatible key, the expressions
"equivalent", "less than" and "greater than" take on their obvious interpretations.
]
[#reference_set_of_find_key]
template< class CompatibleKey >
iterator find(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator find(const CompatibleKey & x) const;
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Returns a pointer to an element whose key is equivalent to `x`, or
`end()` if such an element does not exist.
* [*Complexity:] O(log(n)).
[/
template< class CompatibleKey, class CompatibleCompare >
iterator find(const CompatibleKey & x,
const CompatibleCompare & comp);
template< class CompatibleKey, class CompatibleCompare >
const_iterator find(const CompatibleKey & x,
const CompatibleCompare & comp) const;
* [*Requires: ] `(CompatibleKey, CompatibleCompare)` is a compatible extension of
`key_compare.`
* [*Effects:] Returns a pointer to an element whose key is
equivalent to `x`, or `end()` if such an element does not exist.
* [*Complexity:] O(log(n)).
]
[#reference_set_of_count_key]
template< class CompatibleKey >
size_type count(const key_type & x) const;
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Returns the number of elements with key equivalent to `x`.
* [*Complexity:] O(log(n) + count(x)).
[/
template< class CompatibleKey, class CompatibleCompare >
size_type count(const CompatibleKey & x,
const CompatibleCompare & comp) const;
* [*Requires: ] `(CompatibleKey, CompatibleCompare)` is a compatible extension of
`key_compare.`
* [*Effects:] Returns the number of elements with key equivalent to `x`.
* [*Complexity:] O(log(n) + count(x)).
]
[#reference_set_of_lower_bound_key]
template< class CompatibleKey >
iterator lower_bound(const key_type & x);
template< class CompatibleKey >
const_iterator lower_bound(const key_type & x) const;
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Returns an iterator pointing to the first element with key not
less than `x`, or `end()` if such an element does not exist.
* [*Complexity:] O(log(n)).
[#reference_set_of_upper_bound_key]
template< class CompatibleKey >
iterator upper_bound(const key_type & x);
template< class CompatibleKey >
const_iterator upper_bound(const key_type & x) const;
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Returns an iterator pointing to the first element with key greater
than `x`, or `end()` if such an element does not exist.
* [*Complexity:] O(log(n)).
[#reference_set_of_equal_range_key]
template< class CompatibleKey >
std::pair<iterator,iterator>
equal_range(const key_type & x);
template< class CompatibleKey >
std::pair<const_iterator,const_iterator>
equal_range(const key_type & x) const;
* [*Requires: ] `CompatibleKey` is a compatible key of `key_compare`.
* [*Effects:] Equivalent to `make_pair(lower_bound(x),upper_bound(x))`.
* [*Complexity:] O(log(n)).
[endsect]
[section Range operations]
The member function range is not defined for sorted associative
containers, but `[multi]set_of` map views provide it as a convenient utility.
A range or interval is defined by two conditions for the lower and upper
bounds, which are modelled after the following concepts.
Consider a __SGI_STRICT_WEAK_ORDERING__ `Compare` over values of type Key.
A type `LowerBounder` is said to be a lower bounder of `Compare` if
* `LowerBounder` is a `Predicate` over `Key`,
* if `lower(k1)` and `!comp(k2,k1)` then `lower(k2)`,
for every `lower` of type `LowerBounder`, `comp` of type `Compare`, and `k1`, `k2`
of type `Key`.
Similarly, an upper bounder is a type `UpperBounder` such that
* `UpperBounder` is a `Predicate` over `Key`,
* if `upper(k1)` and `!comp(k1,k2)` then `upper(k2)`,
for every `upper` of type `UpperBounder`, `comp` of type `Compare`, and `k1`, `k2`
of type `Key`.
[#reference_set_of_range_lower_upper]
template< class LowerBounder, class UpperBounder>
std::pair<const_iterator,const_iterator> range(
LowerBounder lower, UpperBounder upper) const;
* [*Requires: ] `LowerBounder` and `UpperBounder` are a lower and upper bounder of
`key_compare`, respectively.
* [*Effects:] Returns a pair of iterators pointing to
the beginning and one past the end of the subsequence of elements satisfying
lower and upper simultaneously. If no such elements exist, the iterators both
point to the first element satisfying lower, or else are equal to `end()` if this
latter element does not exist.
* [*Complexity:] O(log(n)).
* [*Variants:] In place of lower or upper (or both), the singular value
`boost::bimap::unbounded` can be provided. This acts as a predicate which
all values of type `key_type` satisfy.
* [*Note:] Only provided for map views.
[endsect]
[section at() 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.
]
[endsect]
[section Serialization]
Views cannot be serialized on their own, but only as part of the `bimap`
into which they are embedded. In describing the additional preconditions and guarantees
associated to `[multi]set_of` views with respect to serialization of their embedding containers,
we use the concepts defined in the `bimap` serialization section.
[blurb [*Operation:] saving of a `bimap` m to an output archive (XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[blurb [*Operation:] loading of a `bimap` m' from an input archive (XML archive) ar.]
* [*Requires:] In addition to the general requirements, `value_comp()` must be
serialization-compatible with `m.get<i>().value_comp()`, where i is the position
of the ordered view in the container.
* [*Postconditions:] On successful loading, each of the elements of `[begin(), end())`
is a restored copy of the corresponding element in `[m.get<i>().begin(), m.get<i>().end())`.
[blurb [*Operation:] saving of an iterator or `const_iterator` it to an output archive
(XML archive) ar.]
* [*Requires: ] `it` is a valid iterator of the view. The associated `bimap`
has been previously saved.
[blurb [*Operation:] loading of an `iterator` or `const_iterator` `it`' from an input archive (
XML archive) ar.]
* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
restored copy of `*it`, otherwise `it`'` == end()`.
* [*Note:] It is allowed that it be a `const_iterator` and the restored `it`' an iterator,
or viceversa.
[endsect]
[endsect]
[endsect]

View File

@@ -0,0 +1,123 @@
[/license
Boost.Bimap
Copyright (c) 2006-2007 Matias Capeletto
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]
[/ QuickBook Document version 1.4 ]
[section unconstrained_set_of Reference]
[section Header "boost/bimap/unconstrained_set_of.hpp" synopsis]
namespace boost {
namespace bimaps {
template< class KeyType >
struct unconstrained_set_of;
struct unconstrained_set_of_relation;
} // namespace bimap
} // namespace boost
[endsect]
[section unconstrained_set_of Views]
An unconstrained_set_of set view is a view with no constraints. The use
of these kind of view boost the bimap performance but the view can not
be accessed. An unconstrained view is an empty class.
namespace boost {
namespace bimaps {
namespace views {
template< ``['-implementation defined parameter list-]`` >
class ``['-implementation defined view name-]``
{
// Empty view
};
} // namespace views
} // namespace bimap
} // namespace boost
In the case of a `bimap< unconstrained_set_of<Left>, ... >`
In the set view:
typedef signature-compatible with relation< Left, ... > key_type;
typedef signature-compatible with relation< Left, ... > value_type;
In the left map view:
typedef Left key_type;
typedef ... data_type;
typedef signature-compatible with std::pair< Left, ... > value_type;
In the right map view:
typedef ... key_type;
typedef Left data_type;
typedef signature-compatible with std::pair< ... , Left > value_type;
[#unconstrained_set_of_complexity_signature]
[section Complexity signature]
We adopt the scheme outlined in the
[link complexity_signature_explanation complexity signature section].
An unconstrained view can not be accessed by the user, but the
formulas to find the order of an operation for a bimap hold with
the following definitions.
The complexity signature of a `unconstrained_set_of` view is:
* copying: `c(n) = 0`
* insertion: `i(n) = 0`
* hinted insertion: `h(n) = 0`
* deletion: `d(n) = 0`
* replacement: `r(n) = 0`
* modifying: `m(n) = 0`
[endsect]
[section Serialization]
Views cannot be serialized on their own, but only as part of the
`bimap` into which they are embedded. In describing the additional
preconditions and guarantees associated to `list_of` views with respect to
serialization of their embedding containers, we use the concepts defined in the
`bimap` serialization section.
[blurb [*Operation:] saving of a `bimap` b to an output archive
(XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[blurb [*Operation:] loading of a `bimap` b' from an input archive
(XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[endsect]
[endsect]
[endsect]

View File

@@ -0,0 +1,824 @@
[/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;
// construct/destroy/copy:
this_type & operator=(const this_type & x);
allocator_type get_allocator() const;
// size and capacity
bool empty() const;
size_type size() const;
size_type max_size() const;
// iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
// modifiers
std::pair< iterator, bool > ``[link reference_unordered_set_of_insert_value insert]``(const value_type & x);
iterator ``[link reference_unordered_set_of_insert_iterator_value insert]``(iterator position, const value_type & x);
template< class InputIterator >
void ``[link reference_unordered_set_of_insert_iterator_iterator insert]``(InputIterator first, InputIterator last);
iterator ``[link reference_unordered_set_of_erase_iterator erase]``(iterator position);
template< class CompatibleKey >
size_type ``[link reference_unordered_set_of_erase_key erase]``(const CompatibleKey & x);
iterator ``[link reference_unordered_set_of_erase_iterator_iterator erase]``(iterator first, iterator last);
bool ``[link reference_unordered_set_of_replace_iterator_value replace]``(iterator position, const value_type & x);
// Only in map views
// {
template< class CompatibleKey >
bool ``[link reference_unordered_set_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
template< class CompatibleData >
bool ``[link reference_unordered_set_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
template< class KeyModifier >
bool ``[link reference_unordered_set_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
template< class DataModifier >
bool ``[link reference_unordered_set_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
// }
void clear();
// observers
key_from_value key_extractor() const;
hasher hash_function() const;
key_equal key_eq() const;
// lookup
template< class CompatibleKey >
iterator ``[link reference_unordered_set_of_find_key find]``(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator ``[link reference_unordered_set_of_find_key find]``(const CompatibleKey & x) const;
template< class CompatibleKey >
size_type ``[link reference_unordered_set_of_count_key count]``(const CompatibleKey & x) const;
template< class CompatibleKey >
std::pair<iterator,iterator>
``[link reference_unordered_set_of_equal_range_key equal_range]``(const CompatibleKey & x);
template< class CompatibleKey >
std::pair<const_iterator,const_iterator>
``[link reference_unordered_set_of_equal_range_key equal_range]``(const CompatibleKey & x) const;
// bucket interface
size_type bucket_count() const;
size_type max_bucket_count() const;
size_type bucket_size(size_type n) const;
size_type bucket(const key_type & k) const;
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;
// hash policy
float load_factor() const;
float max_load_factor() const;
void max_load_factor(float z);
void ``[link reference_unordered_set_of_rehash_size rehash]``(size_type n);
// Only in maps views
// {
typedef ``['-unspecified-]`` data_type;
// Only in for `unordered_set_of` collection type
// {
template<class CompatibleKey>
const data_type & ``[link reference_unordered_set_of_at_key_const at]``(const CompatibleKey & k) const;
// Only if the other collection type is mutable
// {
template<class CompatibleKey>
data_type & ``[link reference_unordered_set_of_operator_bracket_key operator\[\]]``(const CompatibleKey & k);
template<class CompatibleKey>
data_type & ``[link reference_unordered_set_of_at_key at]``(const CompatibleKey & k);
// }
// }
// }
};
} // namespace views
} // namespace bimap
} // namespace boost
In the case of a `bimap< unordered_{multi}set_of<Left>, ... >`
In the set view:
typedef signature-compatible with relation< Left, ... > key_type;
typedef signature-compatible with relation< const Left, ... > value_type;
In the left map view:
typedef Left key_type;
typedef ... data_type;
typedef signature-compatible with std::pair< const Left, ... > value_type;
In the right map view:
typedef ... key_type;
typedef Left data_type;
typedef signature-compatible with std::pair< ... ,const Left > value_type;
[#unordered_set_of_complexity_signature]
[section Complexity signature]
Here and in the descriptions of operations of `unordered_[multi]set_of` views,
we adopt the scheme outlined in the
[link complexity_signature_explanation complexity signature section].
The complexity signature of `unordered_[multi]set_of` view is:
* copying: `c(n) = n * log(n)`,
* insertion: average case `i(n) = 1` (constant), worst case `i(n) = n`,
* hinted insertion: average case `h(n) = 1` (constant), worst case `h(n) = n`,
* deletion: average case `d(n) = 1` (constant), worst case `d(n) = n`,
* replacement:
* if the new element key is equivalent to the original, `r(n) = 1` (constant),
* otherwise, average case `r(n) = 1` (constant), worst case `r(n) = n`,
* modifying: average case `m(n) = 1` (constant), worst case `m(n) = n`.
[endsect]
[section Instantiation types]
`unordered_[multi]set_of` views are instantiated internally to `bimap`
specified by means of the collection type specifiers and the `bimap` itself.
Instantiations are dependent on the following types:
* `Value` from `bimap`,
* `Allocator` from `bimap`,
* `Hash` from the collection type specifier,
* `Pred` from the collection type specifier.
`Hash` is a __SGI_UNARY_FUNCTION__ taking a single argument of type
`key_type` and returning a value of type `std::size_t` in the range
`[0, std::numeric_limits<std::size_t>::max())`.
Pred is a __SGI_BINARY_PREDICATE__ inducing an equivalence relation on elements of
`key_type`. It is required that the `Hash` object return the same value for
keys equivalent under `Pred`.
[endsect]
[section Nested types]
iterator
const_iterator
local_iterator
const_local_iterator
[: These types are models of __SGI_FORWARD_ITERATOR__.
]
[endsect]
[section Constructors, copy and assignment]
As explained in the concepts section,
views do not have public constructors or destructors. Assignment, on the other
hand, is provided.
Upon construction, `max_load_factor()` is 1.0.
this_type & operator=(const this_type & x);
* [*Effects: ] `a = b`;
where a and b are the `bimap` objects to which `*this`
and x belong, respectively.
* [*Returns: ] `*this.`
[endsect]
[section Modifiers]
[#reference_unordered_set_of_insert_value]
std::pair<iterator,bool> insert(const value_type & x);
* [*Effects:] Inserts `x` into the `bimap` to which the view belongs if
* the view is non-unique OR no other element with equivalent key exists,
* AND insertion is allowed by all other views of the `bimap`.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if
insertion took place. On successful insertion, `p.first` points to the element
inserted; otherwise, `p.first` points to an element that caused the insertion to
be banned. Note that more than one element can be causing insertion not to be
allowed.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_unordered_set_of_insert_iterator_value]
iterator insert(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid iterator of the view.
* [*Effects: ] `position` is used as a hint to improve the efficiency of the operation.
Inserts `x` into the `bimap` to which the view belongs if
* the view is non-unique OR no other element with equivalent key exists,
* AND insertion is allowed by all other views of the `bimap`.
* [*Returns:] On successful insertion, an iterator to the newly inserted element.
Otherwise, an iterator to an element that caused the insertion to be banned.
Note that more than one element can be causing insertion not to be allowed.
* [link unordered_set_of_complexity_signature [*Complexity:]] O(H(n)).
* [*Exception safety:] Strong.
[#reference_unordered_set_of_insert_iterator_iterator]
template< class InputIterator>
void insert(InputIterator first, InputIterator last);
* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements of type
`value_type`. `first` and `last` are not iterators into any views of the
`bimap` to which this view belongs. `last` is reachable from first.
* [*Effects: ]
`iterator hint = end();`
`while(first != last) hint = insert(hint, *first++);`
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(m*H(n+m)), where m is the number of elements in `[first, last)`.
* [*Exception safety:] Basic.
[#reference_unordered_set_of_erase_iterator]
iterator erase(iterator position);
* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view.
* [*Effects:] Deletes the element pointed to by `position`.
* [*Returns:] An `iterator` pointing to the element immediately following the one
that was deleted, or `end()` if no such element exists.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(D(n)).
* [*Exception safety:] nothrow.
[#reference_unordered_set_of_erase_key]
template< class CompatibleKey >
size_type erase(const CompatibleKey & x);
* [*Effects:] Deletes the elements with key equivalent to `x`.
* [*Returns:] Number of elements deleted.
* [link unordered_set_of_complexity_signature
[*Complexity:]] Average case, O(1 + m*D(n)), worst case O(n + m*D(n)),
where m is the number of elements deleted.
* [*Exception safety:] Basic.
[#reference_unordered_set_of_erase_iterator_iterator]
iterator erase(iterator first, iterator last);
* [*Requires: ] `[first,last)` is a valid range of the view.
* [*Effects:] Deletes the elements in `[first,last)`.
* [*Returns: ] `last`.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
* [*Exception safety:] nothrow.
[#reference_unordered_set_of_replace_iterator_value]
bool replace(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid dereferenceable `iterator` of the view.
* [*Effects:] Assigns the value `x` to the element pointed to by `position` into
the `bimap` to which the view belongs if, for the value `x`
* the view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation the `bimap` to which the view belongs remains in its original state.
[#reference_unordered_set_of_replace_key_iterator_key]
template< class CompatibleKey >
bool replace_key(iterator position, const CompatibleKey & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `key_type`.
* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if,
* the map view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_unordered_set_of_replace_data_iterator_data]
template< class CompatibleData >
bool replace_data(iterator position, const CompatibleData & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `data_type`.
* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if,
* the map view is non-unique OR no other element with equivalent key exists
(except possibly `*position`),
* AND replacing is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_unordered_set_of_modify_key_iterator_modifier]
template< class KeyModifier >
bool modify_key(iterator position, KeyModifier mod);
* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `key_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the map view is non-unique OR no other element with equivalent key exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[#reference_unordered_set_of_modify_data_iterator_modifier]
template< class DataModifier >
bool modify_data(iterator position, DataModifier mod);
* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `data_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the oppositte map view is non-unique OR no other element with equivalent key in that
view exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[/
[#reference_unordered_set_of_modify_iterator_modifier]
template< class Modifier>
bool modify(iterator position, Modifier mod);
* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of
type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&`
for ['Set View]; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View:] or calls `mod(e.left,e.right)`
for ['Set View] where `e` is the element pointed to by `position` and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
Rearrangement is successful if
* the view is non-unique OR no other element with equivalent key exists,
* AND rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link unordered_set_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly `mod`), then the element pointed to by `position` is erased.
/]
[endsect]
[section Lookup]
`unordered_[multi]set_of` views provide the full lookup functionality required by unordered
associative containers, namely `find`, `count`, and `equal_range`. Additionally,
these member functions are templatized to allow for non-standard arguments,
so extending the types of search operations allowed. The kind of arguments
permissible when invoking the lookup member functions is defined by the
following concept.
[/
Consider a pair `(Hash, Pred)` where `Hash` is a hash functor over values of type
`Key` and `Pred` is a __SGI_BINARY_PREDICATE__ inducing an equivalence relation on `Key`,
with the additional constraint that equivalent keys have the same hash value.
A triplet of types `(CompatibleKey, CompatibleHash, CompatiblePred)` is said to
be a ['compatible extension] of `(Hash, Pred)` if
* `CompatibleHash` is a hash functor on values of type `CompatibleKey`,
* `CompatiblePred` is a __SGI_BINARY_PREDICATE__ over `(Key, CompatibleKey)`,
* `CompatiblePred` is a __SGI_BINARY_PREDICATE__ over `(CompatibleKey, Key)`,
* if `c_eq(ck,k1)` then `c_eq(k1,ck)`,
* if `c_eq(ck,k1)` and `eq(k1,k2)` then `c_eq(ck,k2)`,
* if `c_eq(ck,k1)` and `c_eq(ck,k2)` then `eq(k1,k2)`,
* if `c_eq(ck,k1)` then `c_hash(ck)==hash(k1)`,
for every `c_hash` of type `CompatibleHash`, `c_eq` of type `CompatiblePred`, hash of
type `Hash`, `eq` of type `Pred`, `ck` of type `CompatibleKey` and `k1`, `k2` of type `Key`.
]
A type `CompatibleKey` is said to be a ['compatible key] of `(Hash, Pred)`
if `(CompatibleKey, Hash, Pred)` is a compatible extension of `(Hash, Pred)`. This
implies that `Hash` and `Pred` accept arguments of type `CompatibleKey`, which usually
means they have several overloads of their corresponding `operator()` member
functions.
[/
In the context of a compatible extension or a compatible key, the expression
"equivalent key" takes on its obvious interpretation.
]
[#reference_unordered_set_of_find_key]
template< class CompatibleKey >
iterator find(const CompatibleKey & x);
template< class CompatibleKey >
const_iterator find(const CompatibleKey & x) const;
* [*Effects:] Returns a pointer to an element whose key is equivalent to `x`,
or `end()` if such an element does not exist.
* [*Complexity:] Average case O(1) (constant), worst case O(n).
[#reference_unordered_set_of_count_key]
template< class CompatibleKey >
size_type count(const CompatibleKey & x) const;
* [*Effects:] Returns the number of elements with key equivalent to `x`.
* [*Complexity:] Average case O(count(x)), worst case O(n).
[#reference_unordered_set_of_equal_range_key]
template< class CompatibleKey >
std::pair<iterator,iterator>
equal_range(const CompatibleKey & x);
template< class CompatibleKey >
std::pair<const_iterator,const_iterator>
equal_range(const CompatibleKey & x) const;
* [*Effects:] Returns a range containing all elements with keys equivalent
to `x` (and only those).
* [*Complexity:] Average case O(count(x)), worst case O(n).
[endsect]
[section at() and operator\[\] - set_of only]
[#reference_unordered_set_of_at_key_const]
template< class CompatibleKey >
const data_type & at(const CompatibleKey & k) const;
* [*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);
* [*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);
* [*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.
]
[endsect]
[section Hash policy]
[#reference_unordered_set_of_rehash_size]
void rehash(size_type n);
* [*Effects:] Increases if necessary the number of internal buckets so that
`size()/bucket_count()` does not exceed the maximum load factor, and
`bucket_count()>=n`.
* [*Postconditions:] Validity of iterators and references to the elements
contained is preserved.
* [*Complexity:] Average case O(size()), worst case O(size(n)2).
* [*Exception safety:] Strong.
[endsect]
[section Serialization]
Views cannot be serialized on their own, but only as part of the
`bimap` into which they are embedded. In describing the
additional preconditions and guarantees associated to `unordered_[multi]set_of` views
with respect to serialization of their embedding containers, we use
the concepts defined in the `bimap` serialization section.
[blurb [*Operation:] saving of a `bimap` b to an output archive
(XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[blurb [*Operation:] loading of a `bimap` b' from an input
archive (XML archive) ar.]
* [*Requires:] Additionally to the general requirements, `key_eq()` must
be serialization-compatible with `m.get<i>().key_eq()`, where i is the
position of the `unordered_[multi]set_of` view in the container.
* [*Postconditions:] On successful loading, the range `[begin(), end())`
contains restored copies of every element in
`[m.get<i>().begin(), m.get<i>().end())`, though not necessarily in
the same order.
[blurb [*Operation:] saving of an `iterator` or `const_iterator` `it` to an output
archive (XML archive) ar.]
* [*Requires: ] `it` is a valid `iterator` of the view. The associated
`bimap` has been previously saved.
[blurb [*Operation:] loading of an iterator or `const_iterator it`' from an
input archive (XML archive) ar.]
* [*Postconditions:] On successful loading, if `it` was dereferenceable then
`*it`' is the restored copy of `*it`, otherwise `it`'` == end()`.
* [*Note:] It is allowed that `it` be a `const_iterator` and the restored
`it`' an `iterator`, or viceversa.
[blurb [*Operation:] saving of a local_iterator or const_local_iterator it
to an output archive (XML archive) ar.]
* [*Requires: ] `it` is a valid local iterator of the view. The associated
`bimap` has been previously saved.
[blurb [*Operation:] loading of a `local_iterator` or `const_local_iterator`
`it`' from an input archive (XML archive) ar.]
* [*Postconditions:] On successful loading, if `it` was dereferenceable then
`*it`' is the restored copy of `*it`; if `it` was `m.get<i>().end(n)` for some n,
then `it`'` == m`'`.get<i>().end(n)` (where `b` is the original `bimap`,
`b`' its restored copy and `i` is the ordinal of the index.)
* [*Note:] It is allowed that `it` be a `const_local_iterator` and the restored
`it`' a `local_iterator`, or viceversa.
[endsect]
[endsect]
[endsect]

841
doc/reference/vector_of.qbk Executable file
View File

@@ -0,0 +1,841 @@
[/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;
// construct / copy / destroy
this_type & operator=(this_type & x);
template< class InputIterator >
void ``[link reference_vector_of_assign_iterator_iterator assign]``(InputIterator first, InputIterator last);
void ``[link reference_vector_of_assign_size_value assign]``(size_type n, const value_type & value);
allocator_type get_allocator() const;
// iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
// capacity
bool empty() const;
size_type size() const;
size_type max_size() const;
size_type ``[link reference_vector_of_capacity capacity]``() const;
void ``[link reference_vector_of_reserve_size reserve]``(size_type m);
void ``[link reference_vector_of_resize_size_value resize]``(size_type n, const value_type & x = value_type());
// access
const_reference operator[](size_type n) const;
const_reference at(size_type n) const;
const_reference front() const;
const_reference back() const;
// modifiers
std::pair<iterator,bool> ``[link reference_vector_of_push_front_value push_front]``(const value_type & x);
void pop_front();
std::pair<iterator,bool> ``[link reference_vector_of_push_back_value push_back]``(const value_type & x);
void pop_back();
std::pair<iterator,bool> ``[link reference_vector_of_insert_iterator_value insert]``(iterator position, const value_type & x);
void ``[link reference_vector_of_insert_iterator_size_value insert]``(iterator position, size_type m, const value_type & x);
template< class InputIterator>
void ``[link reference_vector_of_insert_iterator_iterator_iterator insert]``(iterator position, InputIterator first, InputIterator last);
iterator ``[link reference_vector_of_erase_iterator erase]``(iterator position);
iterator ``[link reference_vector_of_erase_iterator_iterator erase]``(iterator first, iterator last);
bool ``[link reference_vector_of_replace_iterator_value replace]``(iterator position, const value_type & x);
// Only in map views
// {
template< class CompatibleKey >
bool ``[link reference_vector_of_replace_key_iterator_key replace_key]``(iterator position, const CompatibleKey & x);
template< class CompatibleData >
bool ``[link reference_vector_of_replace_data_iterator_data replace_data]``(iterator position, const CompatibleData & x);
template< class KeyModifier >
bool ``[link reference_vector_of_modify_key_iterator_modifier modify_key]``(iterator position, KeyModifier mod);
template< class DataModifier >
bool ``[link reference_vector_of_modify_data_iterator_modifier modify_data]``(iterator position, DataModifier mod);
// }
void clear();
// list operations
void ``[link reference_vector_of_splice_iterator_this splice]``(iterator position, this_type & x);
void ``[link reference_vector_of_splice_iterator_this_iterator splice]``(iterator position, this_type & x, iterator i);
void ``[link reference_vector_of_splice_iterator_this_iterator_iterator splice]``(
iterator position, this_type & x, iterator first, iterator last);
void ``[link reference_vector_of_remove_value remove]``(const value_type & value);
template< class Predicate >
void ``[link reference_vector_of_remove_if_predicate remove_if]``(Predicate pred);
void ``[link reference_vector_of_unique unique]``();
template< class BinaryPredicate >
void ``[link reference_vector_of_unique_predicate unique]``(BinaryPredicate binary_pred);
void ``[link reference_vector_of_merge_this merge]``(this_type & x);
template< typename Compare >
void ``[link reference_vector_of_merge_this_compare merge]``(this_type & x, Compare comp);
void ``[link reference_vector_of_sort sort]``();
template< typename Compare >
void ``[link reference_vector_of_sort_compare sort]``(Compare comp);
void ``[link reference_vector_of_reverse reverse]``();
// rearrange operations
void ``[link reference_vector_of_relocate_iterator_iterator relocate]``(iterator position, iterator i);
void ``[link reference_vector_of_relocate_iterator_iterator_iterator relocate]``(iterator position, iterator first, iterator last);
};
// view comparison
bool operator==(const this_type & v1, const this_type & v2 );
bool operator< (const this_type & v1, const this_type & v2 );
bool operator!=(const this_type & v1, const this_type & v2 );
bool operator> (const this_type & v1, const this_type & v2 );
bool operator>=(const this_type & v1, const this_type & v2 );
bool operator<=(const this_type & v1, const this_type & v2 );
} // namespace views
} // namespace bimap
} // namespace boost
In the case of a `bimap< vector_of<Left>, ... >`
In the set view:
typedef signature-compatible with relation< Left, ... > key_type;
typedef signature-compatible with relation< Left, ... > value_type;
In the left map view:
typedef Left key_type;
typedef ... data_type;
typedef signature-compatible with std::pair< Left, ... > value_type;
In the right map view:
typedef ... key_type;
typedef Left data_type;
typedef signature-compatible with std::pair< ... , Left > value_type;
[#vector_of_complexity_signature]
[section Complexity signature]
Here and in the descriptions of operations of `vector_of` views, we adopt
the scheme outlined in the
[link complexity_signature_explanation complexity signature section].
The complexity signature of `vector_of` view is:
* copying: `c(n) = n * log(n)`,
* insertion: `i(n) = 1` (amortized constant),
* hinted insertion: `h(n) = 1` (amortized constant),
* deletion: `d(n) = m`, where m is the distance from the deleted element to the
end of the sequence,
* replacement: `r(n) = 1` (constant),
* modifying: `m(n) = 1` (constant).
The following expressions are also used as a convenience for writing down some
of the complexity formulas:
[blurb
`shl(a,b) = a+b` if a is nonzero, 0 otherwise.
`rel(a,b,c) =` if `a<b`, `c-a`, else `a-b`,
]
(`shl` and `rel` stand for ['shift left] and ['relocate], respectively.)
[endsect]
[section Instantiation types]
`vector_of` views are instantiated internally to `bimap` and specified
by means of the collection type specifiers and the bimap itself.
Instantiations are dependent on the following types:
* `Value` from `vector_of`,
* `Allocator` from `bimap`,
[endsect]
[section Constructors, copy and assignment]
As explained in the views concepts section,
views do not have public constructors or destructors.
Assignment, on the other hand, is provided.
this_type & operator=(const this_type & x);
* [*Effects: ] `a=b;`
where a and b are the `bimap` objects to which `*this` and
`x` belong, respectively.
* [*Returns: ] `*this`.
[#reference_vector_of_assign_iterator_iterator]
template< class InputIterator >
void assign(InputIterator first, InputIterator last);
* [*Requires: ] `InputIterator` is a model of __SGI_INPUT_ITERATOR__ over elements
of type `value_type` or a type convertible to `value_type`. `first` and `last` are
not iterators into any view of the `bimap` to which this
view belongs. `last` is reachable from `first`.
* [*Effects: ] `clear(); insert(end(),first,last);`
[#reference_vector_of_assign_size_value]
void assign(size_type n, const value_type & value);
* [*Effects: ] `clear(); for(size_type i = 0; i < n; ++n) push_back(v);`
[endsect]
[section Capacity operations]
[#reference_vector_of_capacity]
size_type capacity() const;
* [*Returns:] The total number of elements `c` such that, when `size() < c`,
back insertions happen in constant time (the general case as described by
i(n) is ['amortized] constant time.)
* [*Note:] Validity of iterators and references to elements is preserved
in all insertions, regardless of the capacity status.
[#reference_vector_of_reserve_size]
void reserve(size_type m);
* [*Effects:] If the previous value of `capacity()` was greater than or equal
to `m`, nothing is done; otherwise, the internal capacity is changed so that
`capacity()>=m`.
* [*Complexity:] If the capacity is not changed, constant; otherwise O(n).
* [*Exception safety:] If the capacity is not changed, nothrow; otherwise, strong.
[#reference_vector_of_resize_size_value]
void resize(size_type n, const value_type & x = value_type());
* [*Effects: ] `if( n > size() ) insert(end(), n-size(), x);`
`else if( n<size() ) erase(begin()+n,end());`
* [*Note:] If an expansion is requested, the size of the view is not guaranteed
to be n after this operation (other views may ban insertions.)
[endsect]
[section Modifiers]
[#reference_vector_of_push_front_value]
std::pair<iterator,bool> push_front(const value_type & x);
* [*Effects:] Inserts x at the beginning of the sequence if no other view
of the `bimap` bans the insertion.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only if
insertion took place. On successful insertion, `p.first` points to the element
inserted; otherwise, `p.first` points to an element that caused the insertion
to be banned. Note that more than one element can be causing insertion not
to be allowed.
* [link vector_of_complexity_signature [*Complexity:]] O(n+I(n)).
* [*Exception safety:] Strong.
[#reference_vector_of_push_back_value]
std::pair<iterator,bool> push_back(const value_type & x);
* [*Effects:] Inserts `x` at the end of the sequence if no other view of
the `bimap` bans the insertion.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only
if insertion took place. On successful insertion, `p.first` points to the
element inserted; otherwise, `p.first` points to an element that caused
the insertion to be banned. Note that more than one element can be
causing insertion not to be allowed.
* [link vector_of_complexity_signature [*Complexity:]] O(I(n)).
* [*Exception safety:] Strong.
[#reference_vector_of_insert_iterator_value]
std::pair<iterator,bool> insert(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid iterator of the view.
* [*Effects:] Inserts `x` before position if insertion is allowed by all
other views of the `bimap`.
* [*Returns:] The return value is a pair `p`. `p.second` is `true` if and only
if insertion took place. On successful insertion, `p.first` points to the
element inserted; otherwise, `p.first` points to an element that caused the
insertion to be banned. Note that more than one element can be causing
insertion not to be allowed.
* [link vector_of_complexity_signature [*Complexity:]] O(shl(end()-position,1) + I(n)).
* [*Exception safety:] Strong.
[#reference_vector_of_insert_iterator_size_value]
void insert(iterator position, size_type m, const value_type & x);
* [*Requires: ] `position` is a valid iterator of the view.
* [*Effects: ] `for(size_type i = 0; i < m; ++i) insert(position, x);`
* [link vector_of_complexity_signature
[*Complexity:]] O(shl(end()-position,m) + m*I(n+m)).
[#reference_vector_of_insert_iterator_iterator_iterator]
template< class InputIterator >
void insert(iterator position, InputIterator first, InputIterator last);
* [*Requires: ] `position` is a valid iterator of the view. `InputIterator`
is a model of __SGI_INPUT_ITERATOR__ over elements of type `value_type` or a type
convertible to `value_type`. `first` and `last` are not iterators into any view
of the `bimap` to which this view belongs. `last` is reachable
from `first`.
* [*Effects: ] `while(first!=last)insert(position,*first++);`
* [link vector_of_complexity_signature
[*Complexity:]] O(shl(end()-position,m) + m*I(n+m)), where m is the number
of elements in `[first,last)`.
* [*Exception safety:] Basic.
[#reference_vector_of_erase_iterator]
iterator erase(iterator position);
* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Deletes the element pointed to by `position`.
* [*Returns:] An iterator pointing to the element immediately following the
one that was deleted, or `end()` if no such element exists.
* [link vector_of_complexity_signature [*Complexity:]] O(D(n)).
* [*Exception safety:] nothrow.
[#reference_vector_of_erase_iterator_iterator]
iterator erase(iterator first, iterator last);
* [*Requires: ] `[first,last)` is a valid range of the view.
* [*Effects:] Deletes the elements in `[first,last)`.
* [*Returns:] last.
* [link vector_of_complexity_signature
[*Complexity:]] O(m*D(n)), where m is the number of elements in `[first,last)`.
* [*Exception safety:] nothrow.
[#reference_vector_of_replace_iterator_value]
bool replace(iterator position, const value_type & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Assigns the value x to the element pointed to by position into
the `bimap` to which the view belongs if replacing is allowed
by all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link vector_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation the `bimap` to which the view belongs remains in its
original state.
[#reference_vector_of_replace_key_iterator_key]
template< class CompatibleKey >
bool replace_key(iterator position, const CompatibleKey & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `key_type`.
* [*Effects:] Assigns the value `x` to `e.first`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link vector_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_vector_of_replace_data_iterator_data]
template< class CompatibleData >
bool replace_data(iterator position, const CompatibleData & x);
* [*Requires: ] `position` is a valid dereferenceable iterator of the set view.
`CompatibleKey` can be assigned to `data_type`.
* [*Effects:] Assigns the value `x` to `e.second`, where `e` is the element pointed
to by `position` into the `bimap` to which the set view belongs if replacing is allowed by
all other views of the `bimap`.
* [*Postconditions:] Validity of position is preserved in all cases.
* [*Returns: ] `true` if the replacement took place, `false` otherwise.
* [link vector_of_complexity_signature
[*Complexity:]] O(R(n)).
* [*Exception safety:] Strong. If an exception is thrown by some user-provided
operation, the `bimap` to which the set view belongs remains in
its original state.
[#reference_vector_of_modify_key_iterator_modifier]
template< class KeyModifier >
bool modify_key(iterator position, KeyModifier mod);
* [*Requires: ] `KeyModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `key_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
It is successful if the rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link vector_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[#reference_vector_of_modify_data_iterator_modifier]
template< class DataModifier >
bool modify_data(iterator position, DataModifier mod);
* [*Requires: ] `DataModifier` is a model of __SGI_UNARY_FUNCTION__ accepting arguments of
type: `data_type&`; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.second)` where e is the element pointed to by position and
rearranges `*position` into all the views of the `bimap`.
If the rearrangement fails, the element is erased.
It is successful if the rearrangement is allowed by all other views of the `bimap`.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link vector_of_complexity_signature
[*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly mod), then the element pointed to by position is erased.
* [*Note:] Only provided for map views.
[/
[#reference_vector_of_modify_iterator_modifier]
template< class Modifier >
bool modify(iterator position, Modifier mod);
* [*Requires: ] `Modifier` is a model of __SGI_BINARY_FUNCTION__ accepting arguments of
type: `first_type&` and `second_type&` for ['Map View] or `left_type&` and `right_type&`
for ['Set View]; `position` is a valid dereferenceable iterator of the view.
* [*Effects:] Calls `mod(e.first,e.second)` for ['Map View:] or calls `mod(e.left,e.right)`
for ['Set View] where e is the element pointed to by `position` and
rearranges `*position` into all the views of the `bimap`.
Rearrangement on `vector_of` views does not change the position of the
element with respect to the view; rearrangement on other views may or
might not suceed. If the rearrangement fails, the element is erased.
* [*Postconditions:] Validity of `position` is preserved if the operation succeeds.
* [*Returns: ] `true` if the operation succeeded, `false` otherwise.
* [link vector_of_complexity_signature [*Complexity:]] O(M(n)).
* [*Exception safety:] Basic. If an exception is thrown by some user-provided
operation (except possibly `mod`), then the element pointed to by position
is erased.
]
[endsect]
[section List operations]
`vector_of` views replicate the interface of `list_of` views, which
in turn includes the list operations provided by `std::list`. The syntax and
behavior of these operations exactly matches those of `list_of` views, but
the associated complexity bounds differ in general.
[#reference_vector_of_splice_iterator_this]
void splice(iterator position, this_type & x);
* [*Requires: ] `position` is a valid iterator of the view. `&x!=this`.
* [*Effects:] Inserts the contents of `x` before position, in the same order
as they were in `x`. Those elements successfully inserted are erased from `x`.
* [link vector_of_complexity_signature
[*Complexity:]] O(shl(end()-position,x.size()) + x.size()*I(n+x.size()) + x.size()*D(x.size())).
* [*Exception safety:] Basic.
[#reference_vector_of_splice_iterator_this_iterator]
void splice(iterator position, this_type & x,iterator i);
* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
dereferenceable iterator `x`.
* [*Effects:] Inserts the element pointed to by `i` before `position`: if
insertion is successful, the element is erased from `x`. In the special
case `&x==this`, no copy or deletion is performed, and the operation is
always successful. If `position==i`, no operation is performed.
* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
* [link vector_of_complexity_signature
[*Complexity:]] If `&x==this`, O(rel(position,i,i+1));
otherwise O(shl(end()-position,1) + I(n) + D(n)).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, strong.
[#reference_vector_of_splice_iterator_this_iterator_iterator]
void splice(iterator position, this_type & x, iterator first, iterator last);
* [*Requires: ] `position` is a valid iterator of the view. `first` and
`last` are valid iterators of `x`. `last` is reachable from `first`. `position` is
not in the range `[first,last)`.
* [*Effects:] For each element in the range `[first,last)`, insertion is
tried before `position`; if the operation is successful, the element is
erased from `x`. In the special case `&x==this`, no copy or deletion is
performed, and insertions are always successful.
* [*Postconditions:] If `&x==this`, no iterator or reference is invalidated.
* [link vector_of_complexity_signature
[*Complexity:]] If `&x==this`, O(rel(position,first,last));
otherwise O(shl(end()-position,m) + m*I(n+m) + m*D(x.size()))
where m is the number of elements in `[first,last)`.
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_vector_of_remove_value]
void remove(const value_type & value);
* [*Effects:] Erases all elements of the view which compare equal to `value`.
* [link vector_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_vector_of_remove_if_predicate]
template< class Predicate >
void remove_if(Predicate pred);
* [*Effects:] Erases all elements `x` of the view for which `pred(x)` holds.
* [link vector_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_vector_of_unique]
void unique();
* [*Effects:] Eliminates all but the first element from every consecutive
group of equal elements referred to by the iterator `i` in the range
`[first+1,last)` for which `*i==*(i-1)`.
* [link vector_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_vector_of_unique_predicate]
template< class BinaryPredicate >
void unique(BinaryPredicate binary_pred);
* [*Effects:] Eliminates all but the first element from every consecutive
group of elements referred to by the iterator i in the range `[first+1,last)`
for which `binary_pred(*i, *(i-1))` holds.
* [link vector_of_complexity_signature
[*Complexity:]] O(n + m*D(n)), where m is the number of elements erased.
* [*Exception safety:] Basic.
[#reference_vector_of_merge_this]
void merge(this_type & x);
* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over
`value_type`. Both the view and `x` are sorted according to `std::less<value_type>`.
* [*Effects:] Attempts to insert every element of x into the corresponding
position of the view (according to the order). Elements successfully
inserted are erased from `x`. The resulting sequence is stable, i.e. equivalent
elements of either container preserve their relative position. In the special
case `&x==this`, no operation is performed.
* [*Postconditions:] Elements in the view and remaining elements in `x` are
sorted. Validity of iterators to the view and of non-erased elements of `x`
references is preserved.
* [link vector_of_complexity_signature
[*Complexity:]] If `&x==this`, constant;
otherwise O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_vector_of_merge_this_compare]
template< class Compare >
void merge(this_type & x, Compare comp);
* [*Requires: ] `Compare` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
Both the view and `x` are sorted according to comp.
* [*Effects:] Attempts to insert every element of `x` into the corresponding
position of the view (according to `comp`). Elements successfully inserted
are erased from `x`. The resulting sequence is stable, i.e. equivalent
elements of either container preserve their relative position. In the
special case `&x==this`, no operation is performed.
* [*Postconditions:] Elements in the view and remaining elements in `x` are
sorted according to `comp`. Validity of iterators to the view and of
non-erased elements of `x` references is preserved.
* [link vector_of_complexity_signature
[*Complexity:]] If `&x==this`, constant;
otherwise O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
* [*Exception safety:] If `&x==this`, nothrow; otherwise, basic.
[#reference_vector_of_sort]
void sort();
* [*Requires: ] `std::less<value_type>` is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
* [*Effects:] Sorts the view according to `std::less<value_type>`.
The sorting is stable, i.e. equivalent elements preserve their relative position.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n*log(n)).
* [*Exception safety:] Basic.
[#reference_vector_of_sort_compare]
template< class Compare >
void sort(Compare comp);
* [*Requires:] Compare is a __SGI_STRICT_WEAK_ORDERING__ over `value_type`.
* [*Effects:] Sorts the view according to `comp`. The sorting is stable, i.e.
equivalent elements preserve their relative position.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n*log(n)).
* [*Exception safety:] Basic.
[#reference_vector_of_reverse]
void reverse();
* [*Effects:] Reverses the order of the elements in the view.
* [*Postconditions:] Validity of iterators and references is preserved.
* [*Complexity:] O(n).
* [*Exception safety:] nothrow.
[endsect]
[section Rearrange operations]
These operations, without counterpart in `std::list` (although splice provides
partially overlapping functionality), perform individual and global repositioning
of elements inside the index.
[#reference_vector_of_relocate_iterator_iterator]
void relocate(iterator position, iterator i);
* [*Requires: ] `position` is a valid iterator of the view. `i` is a valid
dereferenceable iterator of the view.
* [*Effects:] Inserts the element pointed to by `i` before `position`.
If `position==i`, no operation is performed.
* [*Postconditions:] No iterator or reference is invalidated.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[#reference_vector_of_relocate_iterator_iterator_iterator]
void relocate(iterator position, iterator first, iterator last);
* [*Requires: ] `position` is a valid iterator of the view. `first` and `last` are
valid iterators of the view. `last` is reachable from `first`. `position` is not
in the range `[first,last)`.
* [*Effects:] The range of elements `[first,last)` is repositioned just before
`position`.
* [*Postconditions:] No iterator or reference is invalidated.
* [*Complexity:] Constant.
* [*Exception safety:] nothrow.
[endsect]
[section Serialization]
Views cannot be serialized on their own, but only as part of the `bimap`
into which they are embedded. In describing the additional preconditions and guarantees
associated to `vector_of` views with respect to serialization of their embedding
containers, we use the concepts defined in the `bimap` serialization section.
[blurb [*Operation:] saving of a `bimap` b to an output archive (XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
[blurb [*Operation:] loading of a `bimap` b' from an input archive (XML archive) ar.]
* [*Requires:] No additional requirements to those imposed by the container.
* [*Postconditions:] On successful loading, each of the elements of `[begin(), end())` is a
restored copy of the corresponding element in `[m.get<i>().begin(), m.get<i>().end())`,
where `i` is the position of the `vector_of` view in the container.
[blurb [*Operation:] saving of an `iterator` or `const_iterator` `it` to an output archive (XML archive) ar.]
* [*Requires: ] `it` is a valid iterator of the view. The associated `bimap`
has been previously saved.
[blurb [*Operation:] loading of an `iterator` or `const_iterator` `it`' from an input archive (XML archive) ar.]
* [*Postconditions:] On successful loading, if it was dereferenceable then `*it`' is the
restored copy of `*it`, otherwise `it`'`==end()`.
* [*Note:] It is allowed that it be a `const_iterator` and the restored `it`' an `iterator`,
or viceversa.
[endsect]
[endsect]
[endsect]

19
doc/release_notes.qbk Executable file
View File

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

110
doc/test_suite.qbk Executable file
View File

@@ -0,0 +1,110 @@
[/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_structured_pair.cpp
test_structured_pair.cpp ]]
[Test structured pair class ]]
[[[@../../test/test_relation.cpp
test_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_extra.cpp
test_bimap_extra.cpp ]]
[Additional checks ]]
]
[endsect]

75
doc/toolbox.qbk Executable file
View File

@@ -0,0 +1,75 @@
[/license
Boost.Bimap
Copyright (c) 2006-2007 Matias Capeletto
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]
[/ QuickBook Document version 1.4 ]
[section Bimap Toolbox]
[section Mutant]
[tip
A mutant class defines storage compatible views in its declaration.
You can the use the mutate<View>(m) function to get a view of the
data with zero overhead.
]
__UNDER_CONSTRUCTION__
[endsect]
[section Structured_pair]
[tip
A structured pair allows you to control the order of the two types.
You can instantiate it so the ['second] member appears in the first
position.
]
__UNDER_CONSTRUCTION__
[endsect]
[section Tagged]
[tip
Tagged idiom and support metafunctions.
]
__UNDER_CONSTRUCTION__
[endsect]
[section Relation]
[tip
The bidirectional std::pair cousin.
]
__UNDER_CONSTRUCTION__
[endsect]
[section Container_adaptor]
[tip
Easy way to adapt a container so it behaves different in some aspect.
It is the same concept that is use in iterator_adaptor.
]
__UNDER_CONSTRUCTION__
[endsect]
[endsect]

937
doc/tutorial.qbk Executable file
View File

@@ -0,0 +1,937 @@
[/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 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 following code snippet shows the relation between a bimap and standard
maps.
[@../../example/standard_map_comparison.cpp Go to source code]
[import ../example/standard_map_comparison.cpp]
[code_standard_map_comparison]
[/
__STD_PAIR__
The designer of the STL observed that this was a directed relationship
and named the data that it contains accordingly. A `std::pair` is a
directed relation between *x* and *y*; hence the names `first` for *x* and
`second` for *y* are natural. Note how the code looks.
X x;
Y y;
std::pair
<
X, /* ----> */ Y
> directed_relation(x,y);
directed_relation.first;
directed_relation.second;
The one remaining task is to find a way to represent this framework in C++
code so it is easy to read it and to remember how to write it. The first
thing is to get rid of the std::pair representing the data contained by
the bimap. The two collections are then at the same level, so it is
incorrect to name them as `first`/`second` or `a`/`b`. These names clearly
impose an ordering on the two values.
The solution is to view *x* as the `left` member and *y* as the `right` one. The
`left`-`right` naming puts the two values on the same level and allows us to
refer to the view easily. We can now say: "The map indexed by the left
member", and the meaning is very clear.
__RELATION__
The new type will be called `relation`. It will have two members: one
called `left` and the other `right`. The code now looks as follows:
X x;
Y y;
boost::relation
<
X, /* <---> */ Y
> relation(x,y);
relation.left; relation.right;
]
[endsect]
[endsect]
[section Controlling collection types]
[section Freedom of choice]
As has already been said, in STL maps, you can only control the
constraints from one of the collections, namely the one that you are
viewing. In Boost.Bimap, you can control both and it is as easy as using the STL.
__EXTENDED_MAPPING_FRAMEWORK__
The idea is to use the same constraint names that are used in the
standard. If you don't specify the collection type, Boost.Bimap assumes
that the collection is a set. The instantiation of a bimap with custom
collection types looks like this:
typedef bimap< ``*CollectionType*``_of<A>, ``*CollectionType*``_of<B> > bm_type;
The following is the list of all supported collection types.
[table Collection of Key Types
[[name ][Features ][map view type ]]
[[`set_of` ][['ordered, unique]][`map` ]]
[[`multiset_of` ][['ordered ]][`multimap` ]]
[[`unordered_set_of` ][['hashed, unique ]][`unordered_map` ]]
[[`unordered_multiset_of`][['hashed ]][`unordered_multimap` ]]
[[`list_of` ][['sequenced ]][`list_map` ]]
[[`vector_of` ][['random access ]][`vector_map` ]]
[[`unconstrained_set_of` ][['unconstrained ]][['can not be viewed] ]]
]
`list_of` and `vector_of` map views are not associated with any existing STL
associative containers. They are two examples of unsorted associative
containers. `unconstrained_set_of` allow the user to ignore a view. This
will be explained later.
__BIMAP_STRUCTURES__
The selection of the collection type affects the possible operations that you
can perform with each side of the bimap and the time it takes to do
each. If we have:
typedef bimap< ``*CollectionType*``_of<A>, ``*CollectionType*``_of<B> > bm_type;
bm_type bm;
The following now describes the resulting map views of the bidirectional
map.
* `bm.left` is signature-compatible with *LeftMapType*`<A,B>`
* `bm.right` is signature-compatible with *RightMapType*`<B,A>`
[endsect]
[section Configuration parameters]
Each collection type template has different parameters to control its
behaviour. For example, in `set_of` specification, you can pass a Functor
type that compares two types. All of these parameters are exactly the
same as those of the standard library container, except for the
allocator type. You will learn later how to change the allocator for a
bimap.
The following table lists the meanings of each collection type's parameters.
[table
[[name ][Additional Parameters]]
[[`set_of<T,KeyComp>`
`multiset_of<T,KeyComp>` ]
[[*KeyComp ] is a Functor that compares two types using a less-than operator.
By default, this is `std::less<T>`. ]]
[[`unordered_set_of<T,HashFunctor,EqualKey>`
`unordered_multiset_of<T,HashFunctor,EqualKey>`]
[[*HashFunctor ] converts a `T` object into an `std::size_t` value. By default it is `boost::hash<T>`.
[*EqualKey ] is a Functor that tests two types for equality. By default, the
equality operator is `std::equal_to<T>`. ]]
[[`list_of<T>` ][No additional parameters.]]
[[`vector_of<T>` ][No additional parameters.]]
[[`unconstrained_set_of<T>` ][No additional parameters.]]
]
[endsect]
[section Examples]
[heading Countries Populations]
We want to store countries populations.
The requeriments are:
# Get a list of countries in decresing order of their populations.
# Given a countrie, get their population.
Lets create the appropiate bimap.
typedef bimap<
unordered_set_of< std::string >,
multiset_of< long, std::greater<long> >
> populations_bimap;
First of all countries names are unique identifiers, while two countries
may have the same population. This is why we choose *multi*`set_of` for
populations.
Using a `multiset_of` for population allow us to iterate over the data.
Since listing countries ordered by their names is not a requisite, we can
use an `unordered_set_of` that allows constant order look up.
And now lets use it in a complete example
[@../../example/population_bimap.cpp Go to source code]
[import ../example/population_bimap.cpp]
[code_population_bimap]
[heading Repetitions counter]
We want to count the repetitions for each word in a text and print them
in order of appearance.
[@../../example/repetitions_counter.cpp Go to source code]
[import ../example/repetitions_counter.cpp]
[code_repetitions_counter]
[endsect]
[endsect]
[section The collection of relations type]
[section A new point of view]
Being able to change the collection type of the bimap relation view is another
very important feature. Remember that this view allows the user to see
the container as a group of the stored relations. This view has set
semantics instead of map semantics.
__COLLECTION_TYPE_OF_RELATION__
By default, Boost.Bimap will base the collection type of the relation on the
type of the left collection. If the left collection type is a set, then the collection
type of the relation will be a set with the same order as the left view.
In general, Boost.Bimap users will base the collection type of a relation on
the type of the collection on one of the two sides. However there are times
where it is useful to give this collection other constraints or simply to order
it differently. The user is allowed to choose between:
* left_based
* right_based
* set_of_relation<>
* multiset_of_relation<>
* unordered_set_of_relation<>
* unordered_multiset_of_relation<>
* list_of_relation
* vector_of_relation
* unconstrained_set_of_relation
[tip
The first two options and the last produce faster bimaps, so prefer
these where possible.
]
__MORE_BIMAP_STRUCTURES__
The collection type of relation can be used to create powerful containers. For
example, if you need to maximize search speed, then the best
bidirectional map possible is one that relates elements from an
`unordered_set` to another `unordered_set`. The problem is that this
container cannot be iterated. If you need to know the list of relations
inside the container, you need another collection type of relation. In this
case, a `list_of_relation` is a good choice. The resulting container
trades insertion and deletion time against fast search capabilities and
the possibility of bidirectional iteration.
[@../../example/mighty_bimap.cpp Go to source code]
[code_mighty_bimap]
[endsect]
[section Configuration parameters]
Each collection type of relation has different parameters to control its
behaviour. For example, in the `set_of_relation` specification, you can
pass a Functor type that compares two types. All of the parameters are
exactly as in the standard library containers, except for the type,
which is set to the bimap relation and the allocator type. To help users
in the creation of each functor, the collection type of relation templates
takes an mpl lambda expression where the relation type will be evaluated
later. A placeholder named `_relation` is available to bimap users.
The following table lists the meaning of the parameters for each collection type of
relations.
[table
[[name ][Additional Parameters]]
[[`left_based` ][Not a template.]]
[[`right_based` ][Not a template.]]
[[`set_of_relation<KeyComp>`
`multiset_of_relation<KeyComp>` ]
[[*KeyComp ] is a Functor that compares two types using less than. By
default, the less-than operator is `std::less<_relation>`. ]]
[[`unordered_set_of_relation<HashFunctor,EqualKey>`
`unordered_multiset_of_relation<HashFunctor,EqualKey>`]
[[*HashFunctor ] converts the `relation` into an `std::size_t` value. By default it is `boost::hash<_relation>`.
[*EqualKey ] is a Functor that tests two relations for equality. By default,
the equality operator is `std::equal_to<_relation>`. ]]
[[`list_of_relation` ][Not a template.]]
[[`vector_of_relation` ][Not a template.]]
[[`unconstrained_set_of_relation` ][Not a template.]]
]
[endsect]
[section Examples]
Consider this example:
template< class Rel >
struct RelOrder
{
bool operator()(Rel ra, Rel rb) const
{
return (ra.left+ra.right) < (rb.left+rb.right);
}
};
typedef bimap
<
multiset_of< int >,
multiset_of< int >,
set_of_relation< RelOrder<_relation> >
> bimap_type;
Here the bimap relation view is ordered using the information of
both sides. This container will only allow unique relations because
`set_of_relation` has been used but the elements in each side of the
bimap can be repeated.
struct name {};
struct phone_number {};
typedef bimap
<
tagged< unordered_multiset_of< string >, name >,
tagged< unordered_set_of < int >, phone_number >,
set_of_relation<>
> bimap_type;
In this other case the bimap will relate names to phone numbers.
Names can be repeated and phone numbers are unique. You can perform
quick searches by name or phone number and the container can be viewed
ordered using the relation view.
[endsect]
[endsect]
[section Differences with standard maps]
[section Insertion]
Remember that a map can be interpreted as a relation between two collections.
In bimaps we have the freedom to change both collection types, imposing
constrains in each of them. Some insertions that we give for granted to
success in standard maps fails with bimaps.
For example:
bimap<int,std::string> bm;
bm.left.insert(1,"orange");
bm.left.insert(2,"orange"); // No effect! returns make_pair(iter,false)
The insertion will only succeed if it is allowed by all views of the `bimap`.
In the next snippet we define the right collection as a multiset, when we
try to insert the same two elements the second insertion is allowed by the
left map view because both values are different and it is allowed by the
right map view because it is a non-unique collection type.
bimap<int, multiset_of<std::string> > bm;
bm.left.insert(1,"orange");
bm.left.insert(2,"orange"); // Insertion succeed!
If we use a custom collection of relation type, the insertion has to be
allowed by it too.
[endsect]
[section iterator::value_type]
The relations stored in the Bimap will not be in most cases modifiable
directly by iterators because both sides are used as keys of
['key-based] sets. When a `bimap<A,B>` left view iterator is dereferenced
the return type is ['signature-compatible] with a
`std::pair< const A, const B >`.
However there are some collection types that are not ['key_based], for example
list_of. If a Bimap uses one of these collection types there is no problem with
modifying the data of that side. The following code is valid:
typedef bimap< int, list_of< std::string > > bm_type;
bm_type bm;
bm.insert( bm_type::relation( 1, "one" ) );
...
bm.left.find(1)->second = "1"; // Valid
In this case, when the iterator is dereferenced the return type is
['signature-compatible] with a `std::pair<const int, std::string>`.
The following table shows the constness of the dereferenced data of each
collection type of:
[table
[[Side collection type ][Dereferenced data]]
[[`set_of` ][['constant]]]
[[`multiset_of` ][['constant]]]
[[`unordered_set_of` ][['constant]]]
[[`unordered_multiset_of`][['constant]]]
[[`list_of` ][['mutable] ]]
[[`vector_of` ][['mutable] ]]
[[`unconstrained_set_of` ][['mutable] ]]
]
Here are some examples. When dereferenced the iterators returns a type that
is ['signature-compatible] with these types.
[table
[[Bimap type ][Signature-compatible types]]
[[`bimap<A,B>`][
`iterator ` *->* `relation<const A,const B>`
`left_iterator ` *->* `pair<const A,const B>`
`right_iterator` *->* `pair<const B,const A>`
]]
[[`bimap<multiset_of<A>,unordered_set_of<B> >`][
`iterator ` *->* `relation<const A,const B>`
`left_iterator ` *->* `pair<const A,const B>`
`right_iterator` *->* `pair<const B,const A>`
]]
[[`bimap<set_of<A>,list_of<B> >`][
`iterator ` *->* `relation<const A,B>`
`left_iterator ` *->* `pair<const A,B>`
`right_iterator` *->* `pair<B,const A>`
]]
[[`bimap<vector_of<A>,set_of<B> >`][
`iterator ` *->* `relation<A,const B>`
`left_iterator ` *->* `pair<A,const B>`
`right_iterator` *->* `pair<const B,A>`
]]
[[`bimap<list_of<A>,unconstrained_set_of<B> >`][
`iterator ` *->* `relation<A,B>`
`left_iterator ` *->* `pair<A,B>`
`right_iterator` *->* `pair<B,A>`
]]
]
[endsect]
[section operator\[\] and at()]
`set_of` and `unordered_set_of` map views overload `operator[]` to retrieve the
associated data of a given key only when the other collection type is a
mutable one. In these cases it works in the same way as the standard.
bimap< unorderd_set_of< std::string>, list_of<int> > bm;
bm.left["one"] = 1; // Ok
The standard defines an access function for `map` and `unordered_map`:
const data_type & at(const key_type & k) const;
data_type & at(const key_type & k);
These functions look for a key and returns the associated data value, but
throws a `std::out_of_range` exception if the key is not found.
In bimaps the constant version of these functions is given for `set_of` and
`unorderd_set_of` map views independently of the other collection type.
The mutable version is only provided when the other collection type is
mutable.
The following examples shows the behaviour of `at(key)`
[@../../example/at_function_examples.cpp Go to source code]
[import ../example/at_function_examples.cpp]
[code_at_function_first]
[code_at_function_second]
[/
`set_of` and `unordered_set_of` views overload `operator[]` to retrieve the
associated data of a given key.
The symmetry of bimap imposes some constraints on `operator[]` that are
not found in `std::map` or `std::unordered_map`. If other views are unique,
`bimap::duplicate_value` is thrown whenever an assignment is attempted to
a value that is already a key in these views. As for
`bimap::value_not_found`, this exception is thrown while trying to access
a non-existent key: this behaviour differs from the standard containers,
which automatically assigns a default value to non-existent keys referred to
by `operator[]`.
const data_type & operator[](const typename key_type & k) const;
[: Returns the `data_type` reference that is associated with `k`, or
throws `bimap::value_not_found` if such an element does not exist.
]
``['-unspecified data_type proxy-]`` operator[](const typename key_type & k);
[: Returns a proxy to a `data_type` associated with `k` and the
bimap. The proxy behaves as a reference to the `data_type` object. If this
proxy is read and `k` was not in the bimap, the bimap::value_not_found is
thrown. If it is written then `bimap::duplicate_value` is thrown if the
assignment is not allowed by one of the other views of the `bimap`.
]
The following example shows the behaviour of `operator[]`
bimap<int,std::string> bm;
bm.left[1] = "one"; // Ok
bm.right["two"] = 2; // Ok
if( bm.left[3] == "three" ) // throws bimap::value_not_found
{
...
}
bm.left[3] = "one"; // throws bimap::duplicate_value
]
[endsect]
[section Complexity of operations]
The complexity of some operations is different in bimaps. Read
[link complexity_signature_explanation the reference] to find the
complexity of each function.
[endsect]
[endsect]
[section Useful functions]
[section Projection of iterators]
Iterators can be projected to any of the three views of the bimap.
A bimap provides three member functions to cope with projection: `project_left`,
`project_right` and `project_up`, with projects iterators to the ['left map view],
the ['right map view] and the ['collection of relations view]. These functions
take any iterator from the bimap and retrieve an iterator over the projected view
pointing to the same element.
[import ../example/projection.cpp]
Here is an example that uses projection:
[@../../example/projection.cpp Go to source code]
[code_projection_years]
[endsect]
[section replace and modify]
[import ../example/tutorial_modify_and_replace.cpp]
These functions are members of the views of a bimap that are not founded in
their standard counterparts.
The `replace` family member functions performs in-place replacement of a given
element as the following example shows:
[@../../example/tutorial_modify_and_replace.cpp Go to source code]
[code_tutorial_replace]
`replace` functions performs this substitution in such a manner that:
* The complexity is constant time if the changed element retains its original order
with respect to all views; it is logarithmic otherwise.
* Iterator and reference validity are preserved.
* The operation is strongly exception-safe, i.e. the `bimap` remains unchanged if
some exception (originated by the system or the user's data types) is thrown.
`replace` functions are powerful operations not provided by standard STL containers,
and one that is specially handy when strong exception-safety is required.
The observant reader might have noticed that the convenience of replace comes at a
cost: namely the whole element has to be copied ['twice] to do the updating (when
retrieving it and inside `replace`). If elements are expensive to copy, this may
be quite a computational cost for the modification of just a tiny part of the
object. To cope with this situation, Boost.Bimap provides an alternative
updating mechanism: `modify` functions.
`modify` functions accepts a functor (or pointer to function) taking a reference
to the data to be changed, thus eliminating the need for spurious copies. Like
`replace` functions, `modify` functions does preserve the internal orderings of
all the indices of the `bimap`. However, the semantics of modify functions are not
entirely equivalent to replace functions. Consider what happens if a collision occurs
as a result of modifying the element, i.e. the modified element clashes with another
with respect to some unique view. In the case of `replace` functions, the original
value is kept and the method returns without altering the container, but `modify`
functions cannot afford such an approach, since the modifying functor leaves no
trace of the previous value of the element. Integrity constraints thus lead to the
following policy: when a collision happens in the process of calling a modify functions,
the element is erased and the method returns false. This difference in behavior
between `replace` and `modify` functions has to be considered by the programmer on
a case-by-case basis.
Boost.Bimap defines new placeholders named `_key` and `_data` to allow a sounder solution.
You have to include `<boost/bimap/support/lambda.hpp>` to use them.
[/
Boost.Bimap defines new placeholders to allow a sounder solution. For
pairs, two new placeholders are instantiated: `_first` and `_second`, and
for a relation, two more complete the set: `_left` and `_right`.
]
[@../../example/tutorial_modify_and_replace.cpp Go to source code]
[code_tutorial_modify]
[endsect]
[section Retrieval of ranges]
[import ../example/tutorial_range.cpp]
Standard `lower_bound` and `upper_bound` functions can be used to lookup for
all the elements in a given range.
Suppose we want to retrieve the elements from a `bimap<int,std::string>`
where the left value is in the range `[20,50]`
[code_tutorial_range_standard_way]
Subtle changes to the code are required when strict inequalities are considered.
To retrieve the elements greater than 20 and less than 50, the code has to be
rewritten as
[code_tutorial_range_standard_way_subtle_changes]
To add to this complexity, the careful programmer has to take into account that
the lower and upper bounds of the interval searched be compatible: for instance,
if the lower bound is 50 and the upper bound is 20, the iterators `iter_first` and
`iter_second` produced by the code above will be in reverse order, with possibly
catastrophic results if a traversal from `iter_first` to `iter_second` is tried.
All these details make range searching a tedious and error prone task.
The range member function, often in combination with lambda expressions,
can greatly help alleviate this situation:
[code_tutorial_range]
`range` simply accepts predicates specifying the lower and upper bounds of
the interval searched. Please consult the reference for a detailed explanation
of the permissible predicates passed to range.
One or both bounds can be omitted with the special unbounded marker:
[code_tutorial_range_unbounded]
[@../../example/tutorial_range.cpp Go to source code]
[endsect]
[endsect]
[section Bimaps with user defined names]
[import ../example/user_defined_names.cpp]
In the following example, the library user inserted comments to guide
future programmers:
[@../../example/user_defined_names.cpp Go to source code]
[code_user_defined_names_untagged_version]
In Boost.Bimap there is a better way to document the code and
in the meantime helping you to write more mantainable and readable code.
You can tag the two collections of the bimap so they can be
accessed by more descriptive names.
__TAGGED__
A tagged type is a type that has been labelled using a tag. A tag is any
valid C++ type. In a bimap, the types are always tagged. If you do not
specify your own tag, the container uses `member_at::left` and
`member_at::right` to tag the left and right sides respectively. In order
to specify a custom tag, the collection type specification 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< tagged< int, Left >, tagged< int, Right > bm_type;
bm_type bm;
//...
bm_type::iterator iter = bm.begin();
bm_type::left_iterator left_iter = bm.left.begin();
bm_type::right_iterator right_iter = bm.right.begin();
[table Equivalence of expresions using user defined names
[[Untagged version] [Tagged version] ]
[[`bm.left`] [`bm.by<Left>()`] ]
[[`bm.right`] [`bm.by<Right>()`] ]
[[`bm_type::left_map`] [`bm::map_by<Left>::type`] ]
[[`bm_type::right_value_type`] [`bm::map_by<Right>::value_type`] ]
[[`bm_type::left_iterator`] [`bm::map_by<Left>::iterator`] ]
[[`bm_type::right_const_iterator`][`bm::map_by<Right>::const_iterator`]]
[[`iter->left`] [`iter->get<Left>()`] ]
[[`iter->right`] [`iter->get<Right>()`] ]
[[`left_iter->first`] [`left_iter->get<Left>()`] ]
[[`left_iter->second`] [`left_iter->get<Right>()`] ]
[[`right_iter->first`] [`right_iter->get<Right>()`] ]
[[`right_iter->second`] [`right_iter->get<Left>()`] ]
[[`bm.project_left(iter)`] [`bm.project<Left>(iter)`] ]
[[`bm.project_right(iter)`] [`bm.project<Right>(iter)`] ]
]
[endsect]
[section Unconstrained Sets]
Unconstrained sets allow the user to disable one of the views of a
bimap. Doing so makes the bimap operations execute faster and reduces
memory consumption. This completes the bidirectional mapping framework
by including unidirectional mappings as a particular case.
Unconstrained sets are useful for the following reasons:
* A bimap type has stronger guarantees than its standard equivalent,
and includes some useful functions (replace, modify) that the standard
does not have.
* You can view the mapping as a collection of relations.
* Using this kind of map makes the code very extensible. If, at any
moment of the development, the need to perform searches from the right
side of the mapping arises, the only necessary change is to the `typedef`.
[import ../example/unconstrained_collection.cpp]
Given this bimap instance,
[code_unconstrained_collection_bimap]
or this standard map one
[code_unconstrained_collection_map]
The following code snippet is valid
[code_unconstrained_collection_common]
But using a bimap has some benefits
[code_unconstrained_collection_only_for_bimap]
[@../../example/unconstrained_collection.cpp Go to source code]
[endsect]
[section Complete instantiation scheme]
To summarize, this is the complete instantiation scheme.
typedef bimap< LeftCollectionType, RightCollectionType [, SetTypeOfRelation ] [,Allocator] > bm;
`{Side}CollectionType` can directly be a type. This defaults to
`set_of<Type>`, or can be a `{CollectionType}_of<Type>` specification.
Additionally, these two parameters can be tagged to specify other tags
instead of the usual `member_at::-Side-` tags. The last two parameters are
used to specify the collection type of the relation 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 a bimap:
bimap<LeftKeyType,RightKeyType>
* set_of_relation_type: based on the left key type
* allocator: default allocator
bimap<LeftKeyType,RightKeyType,Allocator>
* set_of_relation_type: based on the left key type
* allocator: Allocator
bimap<LeftKeyType,RightKeyType,SetOfRelationType>
* set_of_relation_type: SetOfRelationType
* allocator: default allocator
bimap<LeftKeyType,RightKeyType,SetOfRelationType,Allocator>
* set_of_relation_type: SetOfRelationType
* allocator: Allocator
[endsect]
[endsect]

46
example/Jamfile.v2 Executable file
View File

@@ -0,0 +1,46 @@
# 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 projection.cpp ]
;
test-suite "bimap_and_boost"
:
[ run bimap_and_boost/property_map.cpp ]
[ run bimap_and_boost/range.cpp ]
[ run bimap_and_boost/lambda.cpp ]
[ run bimap_and_boost/assign.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 ]
;

View File

@@ -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 <boost/config.hpp>
#include <string>
#include <iostream>
#include <cassert>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/list_of.hpp>
#include <boost/bimap/multiset_of.hpp>
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<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
//<-
*/
//->
//]
}
int main()
{
first_bimap();
second_bimap();
return 0;
}

View File

@@ -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 <boost/config.hpp>
#include <string>
#include <boost/assign/list_of.hpp>
#include <boost/assign/list_inserter.hpp>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/bimap/list_of.hpp>
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;
}

View File

@@ -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 <boost/config.hpp>
#include <string>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/support/lambda.hpp>
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;
}

View File

@@ -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 <boost/config.hpp>
#include <iostream>
#include <string>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/bimap/property_map/set_support.hpp>
using namespace boost::bimaps;
//[ code_bimap_and_boost_property_map
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;
}
//]

122
example/bimap_and_boost/range.cpp Executable file
View File

@@ -0,0 +1,122 @@
// 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/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
//[ 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<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;
}
//]
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/bimap/support/lambda.hpp>
#include <boost/bind.hpp>
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<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;
}
//]

View File

@@ -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 <boost/config.hpp>
#include <fstream>
#include <string>
#include <cassert>
#include <boost/bimap/bimap.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
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<const bm_type&>(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;
}

View File

@@ -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<const FromType,const ToType> such that no two elements exists with
// the same first or second value (std::map only guarantees uniqueness of the
// first member).
// Fast lookup is provided for both keys. The program features a tiny
// Spanish-English dictionary with online query of words in both languages.
#include <boost/config.hpp>
//[ code_mi_to_b_path_bidirectional_map
#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 /*< `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;
}
//]

View File

@@ -0,0 +1,99 @@
// 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 <boost/config.hpp>
//[ code_mi_to_b_path_hashed_indices
#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
<
tagged<
multiset_of< unsigned int, std::greater<unsigned int> >,
occurrences
>,
tagged<
unordered_set_of< 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;
}
//]

View File

@@ -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 <boost/config.hpp>
//[ code_mi_to_b_path_mi_bidirectional_map
#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;
}
//]

View File

@@ -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 <boost/config.hpp>
//[ code_mi_to_b_path_mi_hashed_indices
#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;
}
//]

View File

@@ -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<const FromType,const ToType> such that no two elements exists with
// the same first or second value (std::map only guarantees uniqueness of the
// first member).
// Fast 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 <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;
}
//]

109
example/mighty_bimap.cpp Executable file
View File

@@ -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 <boost/config.hpp>
//[ code_mighty_bimap
#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
<
tagged< unordered_set_of< std::string >, spanish >,
tagged< unordered_set_of< 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;
}
//]

75
example/population_bimap.cpp Executable file
View File

@@ -0,0 +1,75 @@
// 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 <iostream>
#include <string>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
using namespace boost::bimaps;
int main()
{
//[ code_population_bimap
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
/*<< 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. >>*/
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;
}

60
example/projection.cpp Executable file
View File

@@ -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 <boost/config.hpp>
#include <string>
#include <iostream>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
using namespace boost::bimaps;
void years_example()
{
//[ code_projection_years
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;
//]
}
int main()
{
years_example();
return 0;
}

91
example/repetitions_counter.cpp Executable file
View File

@@ -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 <boost/config.hpp>
#include <iostream>
#include <boost/tokenizer.hpp>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/list_of.hpp>
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<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 )
{
/*<< 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;
}

82
example/simple_bimap.cpp Executable file
View File

@@ -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 <boost/config.hpp>
//[ code_simple_bimap
#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;
}
//]

View File

@@ -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 <boost/config.hpp>
#include <string>
#include <iostream>
#include <map>
#include <boost/bimap/bimap.hpp>
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<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;
}
//]

102
example/step_by_step.cpp Executable file
View File

@@ -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 <boost/config.hpp>
#include <iostream>
#include <cassert>
// A convinience header is avaiable in the boost directory:
#include <boost/bimap.hpp>
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;
}
//]

86
example/tagged_simple_bimap.cpp Executable file
View File

@@ -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 <boost/config.hpp>
//[ code_tagged_simple_bimap
#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;
/*<< `results.by<place>()` is equivalent to `results.right` >>*/
for( results_bimap::map_by<place>::const_iterator
i = results.by<place>().begin(),
iend = results.by<place>().end() ;
i != iend; ++i )
{
/*<< `get<Tag>` works for each view of the bimap >>*/
std::cout << i->get<place >() << ") "
<< i->get<country>() << std::endl;
}
std::cout << std::endl
<< "Countries names ordered alfabetically along with"
"their final position:"
<< std::endl;
/*<< `results.by<country>()` is equivalent to `results.left` >>*/
for( 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;
}
//]

View File

@@ -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;
}
//]

97
example/tutorial_range.cpp Executable file
View File

@@ -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 <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;
// ...
std::pair< bm_type::left_iterator, bm_type::left_iterator > 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;
}

View File

@@ -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;
}

142
example/user_defined_names.cpp Executable file
View File

@@ -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 >,
tagged< multiset_of<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;
}

18
include/boost/bimap.hpp Normal file
View File

@@ -0,0 +1,18 @@
// 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)
// Convenience header
#include <boost/bimap/bimap.hpp>
namespace boost
{
using ::boost::bimaps::bimap;
}

433
include/boost/bimap/bimap.hpp Executable file
View File

@@ -0,0 +1,433 @@
// 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)
/// \file bimap.hpp
/// \brief Includes the basic bimap container
/** \mainpage notitle
\n
\image html http://matias.capeletto.googlepages.com/boost.bimap.reference.logo.png
\section Introduction
This is the complete reference of Boost.Bimap.
After getting a good understanding of the library from a user perspective
the next step will be:
- Understand the tagged idiom. (boost::bimaps::tags)
- Understand the internals of the relation class (boost::bimaps::relation)
- Read the container_adaptor toolbox docs (boost::bimaps::container_adaptor)
- Understand the internals of the bimap class. (boost::bimaps, boost::bimaps::views
and boost::bimaps::detail)
**/
/** \defgroup mutant_group mutant idiom
\brief A safe wrapper around reinterpret_cast
**/
/** \defgroup relation_group relation
\brief The relation
**/
/** \defgroup tags_group tagged idiom
\brief The tagged idiom
**/
#ifndef BOOST_BIMAP_BIMAP_HPP
#define BOOST_BIMAP_BIMAP_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/detail/user_interface_config.hpp>
#include <boost/mpl/aux_/na.hpp>
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
#include <boost/serialization/nvp.hpp>
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
// Boost.Bimap
#include <boost/bimap/detail/bimap_core.hpp>
#include <boost/bimap/detail/modifier_adaptor.hpp>
#include <boost/bimap/relation/support/data_extractor.hpp>
#include <boost/bimap/relation/support/member_with_tag.hpp>
#include <boost/bimap/support/map_type_by.hpp>
#include <boost/bimap/support/map_by.hpp>
#include <boost/bimap/support/iterator_type_by.hpp>
/// \brief The namespace where all the boost libraries lives.
namespace boost {
/// \brief Boost.Bimap library namespace
/**
All the entities in the library are defined in this namespace.
**/
namespace bimaps {
/// \brief The bimap class is the entry point to the library.
/**
This class manages the instantiation of the desired bimap type.
As there are several types of bidirectional maps that can be
created using it, the main job of it is to find the desired
type. This is done using metaprogramming to obtain the relation
type that will be stored, the map_view type of each side and
the set_view type of the general relationship. The instantiation
is kept simple using an extended standard set theory, where a
bidirectional map type is defined by the set types it relates.
For example, a bidirectional map that has multimap semantics
viewed from both sides is defined by specifying that the two
keys sets are of \c multiset_of<Key> type.
This allows the bimap class to support seamingless N-N, 1-N,
ordered/unordered and even vector-list types of mapping.
The three last parameters are used to specify the set type of
the relation, an inplace hooked data class and the allocator
type. As a help to the bimap user, these parameters support
default types but use a special idiom that allow them to be
specified without interleaving the usual use_default keyword.
The possible bimap instantiation are enumerated here:
\c {Side}KeyType can be directly a type, this is default to
\c set_of<{Side}KeyType>, or can be a \c {SetType}_of<Type>
specification. Additionally this two parameters can be tagged
to specify others tags instead of the usual \c member_at::{Side}
ones.
\code bimap<LeftKeyType,RightKeyType> \endcode
- \b set_of_relation_type: based on the left key type
- \b hook_data: no additional data
- \b allocator: default allocator
\code bimap<LeftKeyType,RightKeyType> \endcode
- \b set_of_relation_type: based on the left key type
- \b hook_data: no additional data
- \b allocator: \c Allocator
\code bimap<LeftKeyType,RightKeyType,SetOfRelationType> \endcode
- \b set_of_relation_type: \c SetOfRelationType
- \b hook_data: no additional data
- \b allocator: default allocator
\code bimap<LeftKeyType,RightKeyType,SetOfRelationType,Allocator> \endcode
- \b set_of_relation_type: \c SetOfRelationType
- \b hook_data: no additional data
- \b allocator: \c Allocator
\code bimap<LeftKeyType,RightKeyType,DataToHook> \endcode
- \b set_of_relation_type: based on the left key type
- \b hook_data: \c DataToHook
- \b allocator: default allocator
\code bimap<LeftKeyType,RightKeyType,DataToHook,Allocator> \endcode
- \b set_type_of_relation: based on the left key type
- \b hook_data: \c DataToHook
- \b allocator: \c Allocator
\code bimap<LeftKeyType,RightKeyType,SetOfRelationType,DataToHook> \endcode
- \b set_of_relation_type: \c SetOfRelationType
- \b hook_data: \c DataToHook
- \b allocator: default allocator
\code bimap<LeftKeyType,RightKeyType,SetOfRelationType,DataToHook,Allocator> \endcode
- \b set_of_relation_type: \c SetOfRelationType
- \b hook_data: \c DataToHook
- \b allocator: \c Allocator
**/
template
<
class KeyTypeA, class KeyTypeB,
class AP1 = ::boost::mpl::na,
class AP2 = ::boost::mpl::na,
class AP3 = ::boost::mpl::na
>
class bimap
:
public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>,
public ::boost::bimaps::detail::bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3>
::relation_set
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::detail::
bimap_core<KeyTypeA,KeyTypeB,AP1,AP2,AP3> base_;
BOOST_DEDUCED_TYPENAME base_::core_type core;
public:
// metadata --------------------------------------------------------
/*
// The rest is computed in the core, because it is quite difficult to
// expose a nice interface with so many metaprogramming stuff.
// Here it is the complete metadat list.
// Map by {side} metadata
typedef -unspecified- {side}_tag;
typedef -unspecified- {side}_data_type;
typedef -unspecified- {side}_value_type;
typedef -unspecified- {side}_key_type;
typedef -unspecified- {side}_iterator;
typedef -unspecified- {side}_const_iterator;
------------------------------------------------------------------*/
typedef BOOST_DEDUCED_TYPENAME base_::left_set_type left_set_type;
typedef BOOST_DEDUCED_TYPENAME left_set_type::BOOST_NESTED_TEMPLATE map_view_bind
<
BOOST_DEDUCED_TYPENAME base_::left_tag, base_
>::type left_map;
typedef BOOST_DEDUCED_TYPENAME base_::right_set_type right_set_type;
typedef BOOST_DEDUCED_TYPENAME right_set_type::BOOST_NESTED_TEMPLATE map_view_bind
<
BOOST_DEDUCED_TYPENAME base_::right_tag, base_
>::type right_map;
/// Left map view
left_map left;
/// Right map view
right_map right;
bimap() :
base_::relation_set(
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
>(core)
),
left (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_left_tag
>(core)
),
right (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_right_tag
>(core)
)
{}
template< class InputIterator >
bimap(InputIterator first,InputIterator last) :
base_::relation_set(
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
>(core)
),
core(first,last),
left (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_left_tag
>(core)
),
right (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_right_tag
>(core)
)
{}
bimap(const bimap& x) :
base_::relation_set(
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag
>(core)
),
core(x.core),
left (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_left_tag
>(core)
),
right (
::boost::multi_index::get<
BOOST_DEDUCED_TYPENAME base_::logic_right_tag
>(core)
)
{}
bimap& operator=(const bimap& x)
{
core = x.core;
return *this;
}
// Projection of iterators
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::left_iterator
project_left(IteratorType iter)
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
}
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::left_const_iterator
project_left(IteratorType iter) const
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_left_tag>(iter.base());
}
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::right_iterator
project_right(IteratorType iter)
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
}
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::right_const_iterator
project_right(IteratorType iter) const
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_right_tag>(iter.base());
}
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::relation_set::iterator
project_up(IteratorType iter)
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
}
template< class IteratorType >
BOOST_DEDUCED_TYPENAME base_::relation_set::const_iterator
project_up(IteratorType iter) const
{
return core.template project<
BOOST_DEDUCED_TYPENAME base_::logic_relation_set_tag>(iter.base());
}
// Support for tags
template< class Tag, class IteratorType >
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
iterator_type_by<Tag,bimap>::type
project(IteratorType iter
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
{
return core.template project<Tag>(iter.base());
}
template< class Tag, class IteratorType >
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
const_iterator_type_by<Tag,bimap>::type
project(IteratorType iter
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag)) const
{
return core.template project<Tag>(iter.base());
}
template< class Tag >
struct map_by :
public ::boost::bimaps::support::map_type_by<Tag,bimap>::type
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
map_type_by<Tag,bimap>::type type;
private: map_by() {}
};
template< class Tag >
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
map_type_by<Tag,bimap>::type &
by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
{
return ::boost::bimaps::support::map_by<Tag>(*this);
}
template< class Tag >
const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
map_type_by<Tag,bimap>::type &
by(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const
{
return ::boost::bimaps::support::map_by<Tag>(*this);
}
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
// Serialization support
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & serialization::make_nvp("mi_core",core);
}
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};
} // namespace bimaps
} // namespace boost
/** \namespace boost::bimaps::support
\brief Metafunctions to help working with bimaps.
**/
/** \namespace boost::bimaps::views
\brief Bimap views.
**/
/** \namespace boost::bimaps::views::detail
\brief Bimap views details.
**/
// Include basic tools for user commodity
#include <boost/bimap/tags/tagged.hpp>
#include <boost/bimap/relation/member_at.hpp>
#include <boost/multi_index/detail/unbounded.hpp>
// Bring the most used namespaces directly to the user main namespace
namespace boost {
namespace bimaps {
using ::boost::bimaps::tags::tagged;
namespace member_at = ::boost::bimaps::relation::member_at;
using ::boost::multi_index::unbounded;
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_BIMAP_HPP

View File

@@ -0,0 +1,289 @@
// 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)
/// \file container_adaptor/associative_container_adaptor.hpp
/// \brief Container adaptor to build a type that is compliant to the concept of an associative container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <utility>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
#include <boost/bimap/container_adaptor/container_adaptor.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Base, class Iterator, class ConstIterator, class KeyType,
class IteratorToBaseConverter, class IteratorFromBaseConverter,
class ValueToBaseConverter, class ValueFromBaseConverter, class KeyToBaseConverter,
class FunctorsFromDerivedClasses
>
struct associative_container_adaptor_base
{
typedef container_adaptor
<
Base,
Iterator, ConstIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter , ValueFromBaseConverter,
BOOST_DEDUCED_TYPENAME mpl::push_front<
FunctorsFromDerivedClasses,
BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyToBaseConverter>,
// {
detail::key_to_base_identity
<
BOOST_DEDUCED_TYPENAME Base::key_type, KeyType
>,
// }
// else
// {
KeyToBaseConverter
// }
>::type
>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Container adaptor to build a type that is compliant to the concept of an associative container.
template
<
class Base,
class Iterator,
class ConstIterator,
class KeyType,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class associative_container_adaptor :
public associative_container_adaptor_base
<
Base, Iterator, ConstIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type
{
// MetaData -------------------------------------------------------------
typedef typename associative_container_adaptor_base
<
Base, Iterator, ConstIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type base_;
public:
typedef KeyType key_type;
protected:
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyToBaseConverter>,
// {
detail::key_to_base_identity
<
BOOST_DEDUCED_TYPENAME Base::key_type, KeyType
>,
// }
// else
// {
KeyToBaseConverter
// }
>::type key_to_base;
public:
explicit associative_container_adaptor(Base & c)
: base_(c) {}
protected:
typedef associative_container_adaptor associative_container_adaptor_;
// Interface --------------------------------------------------------------
public:
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::size_type erase(const CompatibleKey & k)
{
return this->base().erase
(
this->template functor<key_to_base>()(k)
);
}
// As we redefine erase, the other overloads need to be manually routed
BOOST_DEDUCED_TYPENAME base_::iterator erase(
BOOST_DEDUCED_TYPENAME base_::iterator pos)
{
return base_::container_adaptor_::erase(pos);
}
BOOST_DEDUCED_TYPENAME base_::iterator erase(
BOOST_DEDUCED_TYPENAME base_::iterator first,
BOOST_DEDUCED_TYPENAME base_::iterator last)
{
return base_::container_adaptor_::erase(first,last);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::size_type count(const CompatibleKey & k)
{
return this->base().count(
this->template functor<key_to_base>()(k)
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::iterator find(const CompatibleKey & k)
{
return this->template functor<typename base_::iterator_from_base>()
(
this->base().find(
this->template functor<key_to_base>()(k)
)
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::const_iterator
find(const CompatibleKey & k) const
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()
(
this->base().find(
this->template functor<key_to_base>()(k)
)
);
}
template< class CompatibleKey >
std::pair
<
BOOST_DEDUCED_TYPENAME base_::iterator,
BOOST_DEDUCED_TYPENAME base_::iterator
>
equal_range(const CompatibleKey & k)
{
//TODO check this
std::pair<
BOOST_DEDUCED_TYPENAME Base::iterator,
BOOST_DEDUCED_TYPENAME Base::iterator
> r( this->base().equal_range(
this->template functor<key_to_base>()(k)
)
);
return std::pair
<
BOOST_DEDUCED_TYPENAME base_::iterator,
BOOST_DEDUCED_TYPENAME base_::iterator
>(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base
>() ( r.first ),
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base
>() ( r.second )
);
}
template< class CompatibleKey >
std::pair
<
BOOST_DEDUCED_TYPENAME base_::const_iterator,
BOOST_DEDUCED_TYPENAME base_::const_iterator
>
equal_range(const CompatibleKey & k) const
{
std::pair<
BOOST_DEDUCED_TYPENAME Base::const_iterator,
BOOST_DEDUCED_TYPENAME Base::const_iterator
> r( this->base().equal_range(
this->template functor<key_to_base>()(k)
)
);
return std::pair
<
BOOST_DEDUCED_TYPENAME base_::const_iterator,
BOOST_DEDUCED_TYPENAME base_::const_iterator
>(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base
>() ( r.first ),
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base
>() ( r.second )
);
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP

View File

@@ -0,0 +1,286 @@
// 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)
/// \file container_adaptor/container_adaptor.hpp
/// \brief Container adaptor to build a type that is compliant to the concept of a container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <utility>
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/bimap/container_adaptor/detail/functor_bag.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/front_inserter.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
/// \brief Container Adaptor toolbox, easy way to build new containers from existing ones.
namespace container_adaptor {
/// \brief Container adaptor to build a type that is compliant to the concept of a container.
template
<
class Base,
class Iterator,
class ConstIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class container_adaptor
{
// MetaData -------------------------------------------------------------
public:
typedef Iterator iterator;
typedef ConstIterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME iterator_value < iterator >::type value_type;
typedef BOOST_DEDUCED_TYPENAME iterator_pointer < iterator >::type pointer;
typedef BOOST_DEDUCED_TYPENAME iterator_reference< iterator >::type reference;
typedef BOOST_DEDUCED_TYPENAME iterator_reference< const_iterator >::type const_reference;
typedef BOOST_DEDUCED_TYPENAME Base::size_type size_type;
typedef BOOST_DEDUCED_TYPENAME Base::difference_type difference_type;
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorToBaseConverter>,
// {
::boost::bimaps::container_adaptor::detail::
iterator_to_base_identity
<
BOOST_DEDUCED_TYPENAME Base::iterator , iterator,
BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator
>,
// }
// else
// {
IteratorToBaseConverter
// }
>::type iterator_to_base;
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<IteratorFromBaseConverter>,
// {
::boost::bimaps::container_adaptor::detail::
iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::iterator , iterator,
BOOST_DEDUCED_TYPENAME Base::const_iterator , const_iterator
>,
// }
// else
// {
IteratorFromBaseConverter
// }
>::type iterator_from_base;
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueToBaseConverter>,
// {
::boost::bimaps::container_adaptor::detail::
value_to_base_identity
<
BOOST_DEDUCED_TYPENAME Base::value_type,
value_type
>,
// }
// else
// {
ValueToBaseConverter
// }
>::type value_to_base;
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<ValueFromBaseConverter>,
// {
::boost::bimaps::container_adaptor::detail::
value_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::value_type,
value_type
>,
// }
// else
// {
ValueFromBaseConverter
// }
>::type value_from_base;
// ACCESS -----------------------------------------------------------------
public:
explicit container_adaptor(Base & c) : dwfb(c) {}
protected:
typedef Base base_type;
typedef container_adaptor container_adaptor_;
const Base & base() const { return dwfb.data; }
Base & base() { return dwfb.data; }
// Interface --------------------------------------------------------------
public:
size_type size() const { return base().size(); }
size_type max_size() const { return base().max_size(); }
bool empty() const { return base().empty(); }
iterator begin()
{
return this->template functor<iterator_from_base>()( base().begin() );
}
iterator end()
{
return this->template functor<iterator_from_base>()( base().end() );
}
const_iterator begin() const
{
return this->template functor<iterator_from_base>()( base().begin() );
}
const_iterator end() const
{
return this->template functor<iterator_from_base>()( base().end() );
}
iterator erase(iterator pos)
{
return this->template functor<iterator_from_base>()(
base().erase(this->template functor<iterator_to_base>()(pos))
);
}
iterator erase(iterator first, iterator last)
{
return this->template functor<iterator_from_base>()(
base().erase(
this->template functor<iterator_to_base>()(first),
this->template functor<iterator_to_base>()(last)
)
);
}
void clear()
{
base().clear();
}
template< class InputIterator >
void insert(InputIterator iterBegin, InputIterator iterEnd)
{
for( ; iterBegin != iterEnd ; ++iterBegin )
{
base().insert( this->template
functor<value_to_base>()( *iterBegin )
);
}
}
std::pair<iterator, bool> insert(
BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
{
std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r(
base().insert( this->template functor<value_to_base>()(x) )
);
return std::pair<iterator, bool>( this->template
functor<iterator_from_base>()(r.first),r.second
);
}
iterator insert(iterator pos,
BOOST_DEDUCED_TYPENAME ::boost::call_traits< value_type >::param_type x)
{
return this->template functor<iterator_from_base>()(
base().insert(
this->template functor<iterator_to_base>()(pos),
this->template functor<value_to_base>()(x))
);
}
// Access to functors ----------------------------------------------------
protected:
template< class Functor >
Functor & functor()
{
return dwfb.template functor<Functor>();
}
template< class Functor >
Functor const & functor() const
{
return dwfb.template functor<Functor>();
}
// Data ------------------------------------------------------------------
private:
::boost::bimaps::container_adaptor::detail::data_with_functor_bag
<
Base &,
BOOST_DEDUCED_TYPENAME mpl::copy
<
mpl::vector
<
iterator_to_base,
iterator_from_base,
value_to_base,
value_from_base
>,
mpl::front_inserter< FunctorsFromDerivedClasses >
>::type
> dwfb;
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_CONTAINER_ADAPTOR_HPP

View File

@@ -0,0 +1,101 @@
// 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)
/// \file container_adaptor/detail/comparison_adaptor.hpp
/// \brief Comparison adaptor.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/call_traits.hpp>
#include <functional>
namespace boost {
namespace bimaps {
namespace container_adaptor {
namespace detail {
/// \brief Comparison adaptor
/**
A simple comparison adaptor.
**/
template < class Compare, class NewType, class Converter >
struct comparison_adaptor : std::binary_function<NewType,NewType,bool>
{
comparison_adaptor( const Compare & comp, const Converter & conv)
: compare(comp), converter(conv) {}
bool operator()( BOOST_DEDUCED_TYPENAME call_traits<NewType>::param_type x,
BOOST_DEDUCED_TYPENAME call_traits<NewType>::param_type y) const
{
return compare( converter(x), converter(y) );
}
private:
Compare compare;
Converter converter;
};
template < class Compare, class NewType, class Converter >
struct compatible_comparison_adaptor : std::binary_function<NewType,NewType,bool>
{
compatible_comparison_adaptor( const Compare & comp, const Converter & conv)
: compare(comp), converter(conv) {}
template< class CompatibleTypeLeft, class CompatibleTypeRight >
bool operator()( const CompatibleTypeLeft & x,
const CompatibleTypeRight & y) const
{
return compare( converter(x), converter(y) );
}
private:
Compare compare;
Converter converter;
};
/// \brief Unary Check adaptor
/**
A simple unary check adaptor.
**/
template < class Compare, class NewType, class Converter >
struct unary_check_adaptor : std::unary_function<NewType,bool>
{
unary_check_adaptor( const Compare & comp, const Converter & conv ) :
compare(comp), converter(conv) {}
bool operator()( BOOST_DEDUCED_TYPENAME call_traits<NewType>::param_type x) const
{
return compare( converter(x) );
}
private:
Compare compare;
Converter converter;
};
} // namespace detail
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_COMPARISON_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/detail/functor_bag.hpp
/// \brief Defines a EBO optimizacion helper for functors.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
// This bogus warning will appear when add_const is applied to a
// const volatile reference because we can't detect const volatile
// references with MSVC6.
# pragma warning(push)
# pragma warning(disable:4181)
// warning C4181: qualifier applied to reference type ignored
#endif
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/inherit.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
namespace detail {
/// \brief EBO optimizacion helper for functors
/**
This class is a generalization of a helper class explained in an article by
Nathan C. Myers.\n
See it at \link http://www.cantrip.org/emptyopt.html
**/
template < class Data, class FunctorList >
struct data_with_functor_bag :
public mpl::inherit_linearly<
FunctorList,
mpl::if_< is_base_of< mpl::_2, mpl::_1 >,
// {
mpl::_1,
// }
// else
// {
mpl::inherit< mpl::_1, mpl::_2 >
// }
>
>::type
{
Data data;
data_with_functor_bag() {}
data_with_functor_bag(BOOST_DEDUCED_TYPENAME add_reference<Data>::type const d)
: data(d) {}
template< class Functor >
Functor& functor()
{
return *(static_cast<Functor*>(this));
}
template< class Functor >
const Functor& functor() const
{
return *(static_cast<Functor const *>(this));
}
};
} // namespace detail
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP

View File

@@ -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)
/// \file container_adaptor/detail/identity_converters.hpp
/// \brief Value and iterators identity converters.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Details of the container adaptor toolbox
namespace detail {
/// \brief Iterator identity converter used by default in container adaptors.
/**
If Iterator and ConstIterator are of the same type one of the convert function is not
included.
**/
template
<
class BaseIterator , class Iterator,
class BaseConstIterator , class ConstIterator
>
struct iterator_to_base_identity
{
BaseIterator operator()(Iterator iter) const
{
return BaseIterator(iter);
}
BaseConstIterator operator()(ConstIterator iter) const
{
return BaseConstIterator(iter);
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class BaseIterator, class Iterator >
struct iterator_to_base_identity<BaseIterator,Iterator,BaseIterator,Iterator>
{
BaseIterator operator()(Iterator iter) const
{
return BaseIterator(iter);
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Iterator from base identity converter used by default in container adaptors.
/**
If Iterator and ConstIterator are of the same type one of the convert function is not
included.
**/
template
<
class BaseIterator , class Iterator,
class BaseConstIterator , class ConstIterator
>
struct iterator_from_base_identity
{
Iterator operator()(BaseIterator iter) const
{
return Iterator(iter);
}
ConstIterator operator()(BaseConstIterator iter) const
{
return ConstIterator(iter);
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class BaseIterator, class Iterator, class ConstIterator >
struct iterator_from_base_identity<BaseIterator,Iterator,BaseIterator,ConstIterator>
{
Iterator operator()(BaseIterator iter) const
{
return Iterator(iter);
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Value to base identity converter used by default in container adaptors.
template< class BaseValue, class Value >
struct value_to_base_identity
{
BaseValue operator()(const Value & val) const
{
return BaseValue(val);
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Value >
struct value_to_base_identity< Value, Value >
{
const Value & operator()(const Value & val) const
{
return val;
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Value from base identity converter used by default in container adaptors.
template< class BaseValue, class Value >
struct value_from_base_identity
{
Value operator()(const BaseValue & val) const
{
return Value(val);
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Value >
struct value_from_base_identity<Value,Value>
{
Value & operator()(Value & val) const
{
return val;
}
const Value & operator()(const Value & val) const
{
return val;
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Key to base identity converter used by default in container adaptors.
template< class BaseKey, class Key >
struct key_to_base_identity
{
BaseKey operator()(const Key & k) const
{
return BaseKey(k);
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Key >
struct key_to_base_identity< Key, Key >
{
// As default accept any type as key in order to allow container
// adaptors to work with compatible key types
template< class CompatibleKey >
const CompatibleKey & operator()(const CompatibleKey & k) const
{
return k;
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
} // namespace detail
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_IDENTITY_CONVERTERS_HPP

View File

@@ -0,0 +1,45 @@
// 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)
/// \file container_adaptor/detail/key_extractor.hpp
/// \brief Key extractor for a pair<Key,Data>.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <functional>
namespace boost {
namespace bimaps {
namespace container_adaptor {
namespace detail {
/// \brief Key Extractor
template < class T >
struct key_from_pair_extractor
: std::unary_function< T, BOOST_DEDUCED_TYPENAME T::first_type >
{
bool operator()( const T & p ) { return p.first; }
};
} // namespace detail
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_KEY_EXTRACTOR_HPP

View File

@@ -0,0 +1,62 @@
// 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)
/// \file container_adaptor/detail/non_unique_container_helper.hpp
/// \brief Details for non unique containers
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
/*****************************************************************************/
#define BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS \
\
template <class InputIterator> \
void insert(InputIterator iterBegin, InputIterator iterEnd) \
{ \
for( ; iterBegin != iterEnd ; ++iterBegin ) \
{ \
this->base().insert( \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_to_base>()( \
BOOST_DEDUCED_TYPENAME base_::value_type(*iterBegin)) ); \
} \
} \
\
BOOST_DEDUCED_TYPENAME base_::iterator insert( \
BOOST_DEDUCED_TYPENAME ::boost::call_traits< \
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \
{ \
return this->base().insert( this->template functor< \
BOOST_DEDUCED_TYPENAME base_:: \
value_to_base>()(x) ); \
} \
\
BOOST_DEDUCED_TYPENAME base_::iterator \
insert(BOOST_DEDUCED_TYPENAME base_::iterator pos, \
BOOST_DEDUCED_TYPENAME ::boost::call_traits< \
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( \
this->base().insert(this->template functor< \
BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(pos), \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)) \
); \
}
/*****************************************************************************/
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_NON_UNIQUE_CONTAINER_HELPER_HPP

View File

@@ -0,0 +1,249 @@
// 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)
/// \file container_adaptor/list_adaptor.hpp
/// \brief Container adaptor to easily build a std::list signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/sequence_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/comparison_adaptor.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/call_traits.hpp>
#include <functional>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::list signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class list_adaptor :
public ::boost::bimaps::container_adaptor::sequence_container_adaptor
<
Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::sequence_container_adaptor
<
Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
explicit list_adaptor(Base & c) :
base_(c) {}
protected:
typedef list_adaptor list_adaptor_;
// Interface -------------------------------------------------------------
public:
void splice(Iterator position, list_adaptor & x)
{
this->base().splice(
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()
(position),
x.base()
);
}
void splice(Iterator position, list_adaptor & x, Iterator i)
{
this->base().splice(
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()
(position),
x.base(),
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(i)
);
}
void splice(Iterator position, list_adaptor & x,
Iterator first, Iterator last)
{
this->base().splice(
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()
(position),
x.base(),
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(first),
this->template functor<BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(last)
);
}
void remove(
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type
>::param_type value
)
{
this->base().remove(
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(value)
);
}
template< class Predicate >
void remove_if(Predicate pred)
{
this->base().remove_if(
::boost::bimaps::container_adaptor::detail::unary_check_adaptor
<
Predicate,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>( pred, this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>() )
);
}
void unique()
{
this->base().unique(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::equal_to<BOOST_DEDUCED_TYPENAME base_::value_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>(
std::equal_to<BOOST_DEDUCED_TYPENAME base_::value_type>(),
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>()
)
);
}
template< class BinaryPredicate >
void unique(BinaryPredicate binary_pred)
{
this->base().unique(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
BinaryPredicate,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>( binary_pred,
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>() )
);
}
void merge(list_adaptor & x)
{
this->base().merge(x.base(),
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::less<BOOST_DEDUCED_TYPENAME base_::value_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>(
std::less<BOOST_DEDUCED_TYPENAME base_::value_type>(),
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>()
)
);
}
template< class Compare >
void merge(list_adaptor & x, Compare comp)
{
this->base().merge(x.base(),
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
Compare,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>( comp, this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>() )
);
}
void sort()
{
this->base().sort(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::less<BOOST_DEDUCED_TYPENAME base_::value_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>(
std::less<BOOST_DEDUCED_TYPENAME base_::value_type>(),
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>()
)
);
}
template< class Compare >
void sort(Compare comp)
{
this->base().sort(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
Compare,
BOOST_DEDUCED_TYPENAME Base::value_type,
BOOST_DEDUCED_TYPENAME base_::value_from_base
>( comp, this->template functor<BOOST_DEDUCED_TYPENAME base_::value_from_base>() )
);
}
void reverse()
{
this->base().reverse();
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP

View File

@@ -0,0 +1,282 @@
// 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)
/// \file container_adaptor/list_map_adaptor.hpp
/// \brief Container adaptor.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/bimap/container_adaptor/list_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
#include <boost/bimap/container_adaptor/detail/key_extractor.hpp>
#include <boost/bimap/container_adaptor/detail/comparison_adaptor.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/if.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Base, class Iterator, class ConstIterator,
class ReverseIterator, class ConstReverseIterator,
class IteratorToBaseConverter, class IteratorFromBaseConverter,
class ReverseIteratorFromBaseConverter,
class ValueToBaseConverter, class ValueFromBaseConverter,
class KeyFromBaseValueConverter,
class FunctorsFromDerivedClasses
>
struct list_map_adaptor_base
{
typedef list_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
BOOST_DEDUCED_TYPENAME mpl::push_front<
FunctorsFromDerivedClasses,
BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyFromBaseValueConverter>,
// {
detail::key_from_pair_extractor
<
BOOST_DEDUCED_TYPENAME Iterator::value_type
>,
// }
// else
// {
KeyFromBaseValueConverter
// }
>::type
>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Container adaptor to easily build a list map container
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyFromBaseValueConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class list_map_adaptor :
public list_map_adaptor_base
<
Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyFromBaseValueConverter,
FunctorsFromDerivedClasses
>::type
{
typedef BOOST_DEDUCED_TYPENAME list_map_adaptor_base
<
Base, Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyFromBaseValueConverter,
FunctorsFromDerivedClasses
>::type base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type key_type;
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
protected:
typedef BOOST_DEDUCED_TYPENAME mpl::if_< ::boost::mpl::is_na<KeyFromBaseValueConverter>,
// {
detail::key_from_pair_extractor< BOOST_DEDUCED_TYPENAME Iterator::value_type >,
// }
// else
// {
KeyFromBaseValueConverter
// }
>::type key_from_base_value;
// Access -----------------------------------------------------------------
public:
explicit list_map_adaptor(Base & c) :
base_(c) {}
protected:
typedef list_map_adaptor list_map_adaptor_;
// Functions -------------------------------------------------------------
public:
// The following functions are overwritten in order to work
// with key_type instead of value_type
template< class Predicate >
void remove_if(Predicate pred)
{
this->base().remove_if(
::boost::bimaps::container_adaptor::detail::unary_check_adaptor
<
Predicate,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>( pred, this->template functor<key_from_base_value>() )
);
}
void unique()
{
this->base().unique(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::equal_to<key_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>(
std::equal_to<key_type>(),
this->template functor<key_from_base_value>()
)
);
}
template< class BinaryPredicate >
void unique(BinaryPredicate binary_pred)
{
this->base().unique(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
BinaryPredicate,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>( binary_pred, this->template functor<key_from_base_value>() )
);
}
void merge(list_map_adaptor & x)
{
this->base().merge(x.base(),
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::less<key_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>(
std::less<key_type>(),
this->template functor<key_from_base_value>()
)
);
}
template< class Compare >
void merge(list_map_adaptor & x, Compare comp)
{
this->base().merge(x.base(),
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
Compare,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>( comp, this->template functor<key_from_base_value>() )
);
}
void sort()
{
this->base().sort(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
std::less<key_type>,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>(
std::less<key_type>(),
this->template functor<key_from_base_value>()
)
);
}
template< class Compare >
void sort(Compare comp)
{
this->base().sort(
::boost::bimaps::container_adaptor::detail::comparison_adaptor
<
Compare,
BOOST_DEDUCED_TYPENAME Base::value_type,
key_from_base_value
>( comp, this->template functor<key_from_base_value>() )
);
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_LIST_MAP_ADAPTOR_HPP

View File

@@ -0,0 +1,131 @@
// 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)
/// \file container_adaptor/map_adaptor.hpp
/// \brief Container adaptor to easily build a std::map signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::map signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class map_adaptor :
public ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
// Access -----------------------------------------------------------------
public:
explicit map_adaptor(Base & c) :
base_(c) {}
protected:
typedef map_adaptor map_adaptor_;
// Interface --------------------------------------------------------------
public:
template< class CompatibleKey >
data_type& operator[](const CompatibleKey & k)
{
return this->base()
[this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)];
}
template< class CompatibleKey >
data_type& at(const CompatibleKey & k)
{
return this->base().
at(this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k));
}
template< class CompatibleKey >
const data_type& at(const CompatibleKey & k) const
{
return this->base().
at(this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k));
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MAP_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/multimap_adaptor.hpp
/// \brief Container adaptor to easily build a std::multimap signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::multimap signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class multimap_adaptor :
public ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
// Access -----------------------------------------------------------------
public:
explicit multimap_adaptor(Base & c) :
base_(c) {}
protected:
typedef multimap_adaptor multimap_adaptor_;
public:
BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MULTIMAP_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/multiset_adaptor.hpp
/// \brief Container adaptor to easily build a std::multiset signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::multiset signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class multiset_adaptor :
public ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
explicit multiset_adaptor(Base & c) :
base_(c) {}
protected:
typedef multiset_adaptor multiset_adaptor_;
public:
BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_MULTISET_ADAPTOR_HPP

View File

@@ -0,0 +1,312 @@
// 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)
/// \file container_adaptor/ordered_associative_container_adaptor.hpp
/// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/associative_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/comparison_adaptor.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/operators.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Base, class Iterator, class ConstIterator,
class ReverseIterator, class ConstReverseIterator, class KeyType,
class IteratorToBaseConverter, class IteratorFromBaseConverter,
class ReverseIteratorFromBaseConverter,
class ValueToBaseConverter, class ValueFromBaseConverter,
class KeyToBaseConverter,
class FunctorsFromDerivedClasses
>
struct ordered_associative_container_adaptor_base
{
typedef associative_container_adaptor<
Base, Iterator, ConstIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
BOOST_DEDUCED_TYPENAME mpl::push_front<
FunctorsFromDerivedClasses,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
ReverseIterator,
BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
ConstReverseIterator
>,
// }
// else
// {
ReverseIteratorFromBaseConverter
// }
>::type
>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Container adaptor to build a type that is compliant to the concept of an ordered associative container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class KeyType,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class ordered_associative_container_adaptor :
public ordered_associative_container_adaptor_base
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type,
::boost::totally_ordered
<
ordered_associative_container_adaptor
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator,
KeyType, IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter, FunctorsFromDerivedClasses
>
>
{
// MetaData -------------------------------------------------------------
typedef BOOST_DEDUCED_TYPENAME ordered_associative_container_adaptor_base
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter, KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type base_;
public:
typedef detail::compatible_comparison_adaptor
<
BOOST_DEDUCED_TYPENAME Base::key_compare,
BOOST_DEDUCED_TYPENAME base_::key_type,
BOOST_DEDUCED_TYPENAME base_::key_to_base
> key_compare;
typedef detail::comparison_adaptor
<
BOOST_DEDUCED_TYPENAME Base::value_compare,
BOOST_DEDUCED_TYPENAME base_::value_type,
BOOST_DEDUCED_TYPENAME base_::value_to_base
> value_compare;
typedef ReverseIterator reverse_iterator;
typedef ConstReverseIterator const_reverse_iterator;
protected:
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
reverse_iterator,
BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
const_reverse_iterator
>,
// }
// else
// {
ReverseIteratorFromBaseConverter
// }
>::type reverse_iterator_from_base;
// Access -----------------------------------------------------------------
public:
explicit ordered_associative_container_adaptor(Base & c)
: base_(c) {}
protected:
typedef ordered_associative_container_adaptor
ordered_associative_container_adaptor_;
// Interface --------------------------------------------------------------
public:
reverse_iterator rbegin()
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rbegin() );
}
reverse_iterator rend()
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rend() );
}
const_reverse_iterator rbegin() const
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rbegin() );
}
const_reverse_iterator rend() const
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rend() );
}
key_compare key_comp() const
{
typedef BOOST_DEDUCED_TYPENAME base_::key_to_base key_to_base_;
return key_compare(
this->base().key_comp(),
this->template functor<key_to_base_>()
);
}
value_compare value_comp() const
{
typedef BOOST_DEDUCED_TYPENAME base_::value_to_base value_to_base_;
return value_compare(
this->base().value_comp(),
this->template functor<value_to_base_>()
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::iterator lower_bound(const CompatibleKey & k)
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
this->base().lower_bound(
this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
)
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::const_iterator lower_bound(const CompatibleKey & k) const
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
this->base().lower_bound(
this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
)
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::iterator upper_bound(const CompatibleKey & k)
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
this->base().upper_bound(
this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
)
);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::const_iterator upper_bound(const CompatibleKey & k) const
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(
this->base().upper_bound(
this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)
)
);
}
// Totally ordered implementation
bool operator==(const ordered_associative_container_adaptor & c) const
{
return ( this->base() == c.base() );
}
bool operator<(const ordered_associative_container_adaptor & c) const
{
return ( this->base() < c.base() );
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_ORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP

View File

@@ -0,0 +1,355 @@
// 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)
/// \file container_adaptor/sequence_container_adaptor.hpp
/// \brief Container adaptor to build a type that is compliant to the concept of a weak associative container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <utility>
#include <boost/mpl/if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
#include <boost/bimap/container_adaptor/container_adaptor.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Base, class Iterator, class ConstIterator,
class ReverseIterator, class ConstReverseIterator,
class IteratorToBaseConverter, class IteratorFromBaseConverter,
class ReverseIteratorFromBaseConverter,
class ValueToBaseConverter, class ValueFromBaseConverter,
class FunctorsFromDerivedClasses
>
struct sequence_container_adaptor_base
{
typedef container_adaptor
<
Base, Iterator, ConstIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
BOOST_DEDUCED_TYPENAME mpl::push_front<
FunctorsFromDerivedClasses,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
ReverseIterator,
BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
ConstReverseIterator
>,
// }
// else
// {
ReverseIteratorFromBaseConverter
// }
>::type
>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Container adaptor to build a type that is compliant to the concept of a sequence container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class sequence_container_adaptor :
public sequence_container_adaptor_base
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>::type,
::boost::totally_ordered
<
sequence_container_adaptor
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>
>
{
typedef BOOST_DEDUCED_TYPENAME sequence_container_adaptor_base
<
Base, Iterator, ConstIterator,
ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>::type base_;
// MetaData -------------------------------------------------------------
public:
typedef ReverseIterator reverse_iterator;
typedef ConstReverseIterator const_reverse_iterator;
protected:
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<ReverseIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::reverse_iterator,
reverse_iterator,
BOOST_DEDUCED_TYPENAME Base::const_reverse_iterator,
const_reverse_iterator
>,
// }
// else
// {
ReverseIteratorFromBaseConverter
// }
>::type reverse_iterator_from_base;
// Access -----------------------------------------------------------------
public:
explicit sequence_container_adaptor(Base & c)
: base_(c) {}
protected:
typedef sequence_container_adaptor sequence_container_adaptor_;
// Interface --------------------------------------------------------------
public:
reverse_iterator rbegin()
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rbegin() );
}
reverse_iterator rend()
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rend() );
}
const_reverse_iterator rbegin() const
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rbegin() );
}
const_reverse_iterator rend() const
{
return this->template functor<
reverse_iterator_from_base
>() ( this->base().rend() );
}
void resize(BOOST_DEDUCED_TYPENAME base_::size_type n,
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x =
BOOST_DEDUCED_TYPENAME base_::value_type())
{
this->base().resize(n,
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)
);
}
BOOST_DEDUCED_TYPENAME base_::reference front()
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_from_base>()
(
this->base().front()
);
}
BOOST_DEDUCED_TYPENAME base_::reference back()
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_from_base>()
(
this->base().back()
);
}
BOOST_DEDUCED_TYPENAME base_::const_reference front() const
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_from_base>()
(
this->base().front()
);
}
BOOST_DEDUCED_TYPENAME base_::const_reference back() const
{
return this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_from_base>()
(
this->base().back()
);
}
void push_front(
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x)
{
this->base().push_front(
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x));
}
void pop_front()
{
this->base().pop_front();
}
void push_back(
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x)
{
this->base().push_back(
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x));
}
void pop_back()
{
this->base().pop_back();
}
std::pair<BOOST_DEDUCED_TYPENAME base_::iterator,bool>
insert(BOOST_DEDUCED_TYPENAME base_::iterator position,
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x)
{
std::pair< BOOST_DEDUCED_TYPENAME Base::iterator, bool > r(
this->base().insert(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position),
this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_to_base >()(x)
)
);
return std::pair<BOOST_DEDUCED_TYPENAME base_::iterator, bool>(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(r.first),
r.second
);
}
void insert(BOOST_DEDUCED_TYPENAME base_::iterator position,
BOOST_DEDUCED_TYPENAME base_::size_type m,
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x)
{
this->base().insert(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(position),
m,
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base >()(x)
);
}
template< class InputIterator >
void insert(BOOST_DEDUCED_TYPENAME base_::iterator position,
InputIterator first, InputIterator last)
{
// This is the same problem found in the insert function
// of container_adaptor
// For now, do the simple thing. This can be optimized
for( ; first != last ; ++first )
{
this->base().insert(
this->template functor<
BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()( position ),
this->template functor<
BOOST_DEDUCED_TYPENAME base_::value_to_base >()( *first )
);
}
}
// Totally ordered implementation
bool operator==(const sequence_container_adaptor & c) const
{
return ( this->base() == c.base() );
}
bool operator<(const sequence_container_adaptor & c) const
{
return ( this->base() < c.base() );
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SEQUENCE_CONTAINER_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/set_adaptor.hpp
/// \brief Container adaptor to easily build a std::set signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/aux_/na.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::set signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class set_adaptor :
public ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
ordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
explicit set_adaptor(Base & c) :
base_(c) {}
protected:
typedef set_adaptor set_adaptor_;
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_SET_ADAPTOR_HPP

View File

@@ -0,0 +1,77 @@
// 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)
/// \file container_adaptor/support/iterator_facade_converters.hpp
/// \brief Converter for Boost.Iterators based iterators.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Utilities to help in the construction of a container adaptor
namespace support {
/// \brief Converter for Boost.Iterators based iterators.
/**
Container adaptor is dessigned to play well with Boost.Iterators. This
converter can be used if this library is used to adapt the iterators.
**/
template
<
class Iterator,
class ConstIterator
>
struct iterator_facade_to_base
{
BOOST_DEDUCED_TYPENAME Iterator::base_type operator()(Iterator iter) const
{
return iter.base();
}
BOOST_DEDUCED_TYPENAME ConstIterator::base_type operator()(ConstIterator iter) const
{
return iter.base();
}
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Iterator
>
struct iterator_facade_to_base<Iterator,Iterator>
{
BOOST_DEDUCED_TYPENAME Iterator::base_type operator()(Iterator iter) const
{
return iter.base();
}
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
#undef BOOST_BIMAP_CONTAINER_ADAPTOR_IMPLEMENT_CONVERT_FACADE_FUNCTION
} // namespace support
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_ITERATOR_FACADE_CONVERTERS_HPP

View File

@@ -0,0 +1,293 @@
// 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)
/// \file container_adaptor/unordered_associative_container_adaptor.hpp
/// \brief Container adaptor to build a type that is compliant to the concept of an unordered associative container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/associative_container_adaptor.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template
<
class Base, class Iterator, class ConstIterator,
class LocalIterator, class ConstLocalIterator,
class KeyType,
class IteratorToBaseConverter, class IteratorFromBaseConverter,
class LocalIteratorFromBaseConverter,
class ValueToBaseConverter, class ValueFromBaseConverter,
class KeyToBaseConverter,
class FunctorsFromDerivedClasses
>
struct unordered_associative_container_adaptor_base
{
typedef associative_container_adaptor
<
Base, Iterator, ConstIterator, KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
ValueToBaseConverter , ValueFromBaseConverter,
KeyToBaseConverter,
BOOST_DEDUCED_TYPENAME mpl::push_front<
FunctorsFromDerivedClasses,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<LocalIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::local_iterator,
LocalIterator,
BOOST_DEDUCED_TYPENAME Base::const_local_iterator,
ConstLocalIterator
>,
// }
// else
// {
LocalIteratorFromBaseConverter
// }
>::type
>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Container adaptor to build a type that is compliant to the concept of an unordered associative container.
template
<
class Base,
class Iterator,
class ConstIterator,
class LocalIterator,
class ConstLocalIterator,
class KeyType,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class LocalIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class unordered_associative_container_adaptor :
public unordered_associative_container_adaptor_base
<
Base, Iterator, ConstIterator,
LocalIterator, ConstLocalIterator,
KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type
{
typedef BOOST_DEDUCED_TYPENAME unordered_associative_container_adaptor_base
<
Base, Iterator, ConstIterator,
LocalIterator, ConstLocalIterator,
KeyType,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>::type base_;
// Metadata ---------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Base::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME Base::hasher hasher;
typedef LocalIterator local_iterator;
typedef ConstLocalIterator const_local_iterator;
protected:
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::mpl::is_na<LocalIteratorFromBaseConverter>,
// {
detail::iterator_from_base_identity
<
BOOST_DEDUCED_TYPENAME Base::local_iterator,
local_iterator,
BOOST_DEDUCED_TYPENAME Base::const_local_iterator,
const_local_iterator
>,
// }
// else
// {
LocalIteratorFromBaseConverter
// }
>::type local_iterator_from_base;
// Access -----------------------------------------------------------------
public:
explicit unordered_associative_container_adaptor(Base & c)
: base_(c) {}
protected:
typedef unordered_associative_container_adaptor
unordered_associative_container_adaptor_;
// Interface --------------------------------------------------------------
public:
// bucket interface:
BOOST_DEDUCED_TYPENAME base_::size_type bucket_count() const
{
return this->base().bucket_count();
}
BOOST_DEDUCED_TYPENAME base_::size_type max_bucket_count() const
{
return this->base().max_bucket_count();
}
BOOST_DEDUCED_TYPENAME base_::size_type bucket_size(
BOOST_DEDUCED_TYPENAME base_::size_type n) const
{
return this->base().bucket_size(n);
}
template< class CompatibleKey >
BOOST_DEDUCED_TYPENAME base_::size_type bucket(
const CompatibleKey & k) const
{
typedef BOOST_DEDUCED_TYPENAME base_::key_to_base key_to_base;
return this->base().bucket(
this->template functor<key_to_base>()(k)
);
}
local_iterator begin(BOOST_DEDUCED_TYPENAME base_::size_type n)
{
return this->template functor<
local_iterator_from_base
>() ( this->base().begin(n) );
}
const_local_iterator begin(BOOST_DEDUCED_TYPENAME base_::size_type n) const
{
return this->template functor<
local_iterator_from_base
>() ( this->base().begin(n) );
}
local_iterator end(BOOST_DEDUCED_TYPENAME base_::size_type n)
{
return this->template functor<
local_iterator_from_base
>() ( this->base().end(n) );
}
const_local_iterator end(BOOST_DEDUCED_TYPENAME base_::size_type n) const
{
return this->template functor<
local_iterator_from_base
>() ( this->base().end(n) );
}
// hash policy
float load_factor() const
{
return this->base().load_factor();
}
float max_load_factor() const
{
return this->base().max_load_factor();
}
void max_load_factor(float z)
{
return this->base().max_load_factor(z);
}
void rehash(BOOST_DEDUCED_TYPENAME base_::size_type n)
{
return this->base().rehash(n);
}
// We have redefined end and begin so we have to manually route the old ones
BOOST_DEDUCED_TYPENAME base_::iterator begin()
{
return base_::container_adaptor_::begin();
}
BOOST_DEDUCED_TYPENAME base_::iterator end()
{
return base_::container_adaptor_::end();
}
BOOST_DEDUCED_TYPENAME base_::const_iterator begin() const
{
return base_::container_adaptor_::begin();
}
BOOST_DEDUCED_TYPENAME base_::const_iterator end() const
{
return base_::container_adaptor_::end();
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_ASSOCIATIVE_CONTAINER_ADAPTOR_HPP

View File

@@ -0,0 +1,132 @@
// 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)
/// \file container_adaptor/unordered_map_adaptor.hpp
/// \brief Container adaptor to easily build a std::unordered_map signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/call_traits.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::unordered_map signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class LocalIterator,
class ConstLocalIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class LocalIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class unordered_map_adaptor :
public ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
// Access -----------------------------------------------------------------
public:
explicit unordered_map_adaptor(Base & c) :
base_(c) {}
protected:
typedef unordered_map_adaptor unordered_map_adaptor_;
// Interface --------------------------------------------------------------
public:
template< class CompatibleKey >
data_type& operator[](const CompatibleKey & k)
{
return this->base()
[this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k)];
}
template< class CompatibleKey >
data_type& at(const CompatibleKey & k)
{
return this->base().
at(this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k));
}
template< class CompatibleKey >
const data_type& at(const CompatibleKey & k) const
{
return this->base().
at(this->template functor<BOOST_DEDUCED_TYPENAME base_::key_to_base>()(k));
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MAP_ADAPTOR_HPP

View File

@@ -0,0 +1,110 @@
// 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)
/// \file container_adaptor/unordered_multimap_adaptor.hpp
/// \brief Container adaptor to easily build a std::unordered_multimap signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::unordered_multimap signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class LocalIterator,
class ConstLocalIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class LocalIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class unordered_multimap_adaptor :
public ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
// Access -----------------------------------------------------------------
public:
explicit unordered_multimap_adaptor(Base & c) :
base_(c) {}
protected:
typedef unordered_multimap_adaptor unordered_multimap_adaptor_;
public:
BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTIMAP_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/unordered_multiset_adaptor.hpp
/// \brief Container adaptor to easily build a std::unordered_multiset signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::unordered_multiset signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class LocalIterator,
class ConstLocalIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class LocalIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class unordered_multiset_adaptor :
public ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
explicit unordered_multiset_adaptor(Base & c) :
base_(c) {}
protected:
typedef unordered_multiset_adaptor unordered_multiset_adaptor_;
public:
BOOST_BIMAP_NON_UNIQUE_CONTAINER_ADAPTOR_INSERT_FUNCTIONS
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_MULTISET_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/unordered_set_adaptor.hpp
/// \brief Container adaptor to easily build a std::unordered_set signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/unordered_associative_container_adaptor.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::unordered_set signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class LocalIterator,
class ConstLocalIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class LocalIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class KeyToBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class unordered_set_adaptor :
public ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::
unordered_associative_container_adaptor
<
Base,
Iterator, ConstIterator, LocalIterator, ConstLocalIterator,
BOOST_DEDUCED_TYPENAME Iterator::value_type,
IteratorToBaseConverter, IteratorFromBaseConverter,
LocalIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
KeyToBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
explicit unordered_set_adaptor(Base & c) :
base_(c) {}
protected:
typedef unordered_set_adaptor unordered_set_adaptor_;
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_UNORDERED_SET_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/vector_adaptor.hpp
/// \brief Container adaptor to easily build a std::vector signature compatible container.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/container_adaptor/sequence_container_adaptor.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor to easily build a std::vector signature compatible container.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class vector_adaptor :
public ::boost::bimaps::container_adaptor::sequence_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef ::boost::bimaps::container_adaptor::sequence_container_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
> base_;
// Access -----------------------------------------------------------------
public:
vector_adaptor() {}
explicit vector_adaptor(Base & c) :
base_(c) {}
protected:
typedef vector_adaptor vector_adaptor_;
// Interface --------------------------------------------------------------
public:
BOOST_DEDUCED_TYPENAME base_::size_type capacity() const
{
return this->base().capacity();
}
void reserve(BOOST_DEDUCED_TYPENAME base_::size_type m)
{
this->base().resize(m);
}
void resize(BOOST_DEDUCED_TYPENAME base_::size_type n,
BOOST_DEDUCED_TYPENAME ::boost::call_traits<
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x =
BOOST_DEDUCED_TYPENAME base_::value_type())
{
this->base().resize(n,
this->template functor<BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)
);
}
BOOST_DEDUCED_TYPENAME base_::const_reference
operator[](BOOST_DEDUCED_TYPENAME base_::size_type n) const
{
return this->base().operator[](n);
}
BOOST_DEDUCED_TYPENAME base_::const_reference
at(BOOST_DEDUCED_TYPENAME base_::size_type n) const
{
return this->base().at(n);
}
BOOST_DEDUCED_TYPENAME base_::reference
operator[](BOOST_DEDUCED_TYPENAME base_::size_type n)
{
return this->base().operator[](n);
}
BOOST_DEDUCED_TYPENAME base_::reference
at(BOOST_DEDUCED_TYPENAME base_::size_type n)
{
return this->base().at(n);
}
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_ADAPTOR_HPP

View File

@@ -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)
/// \file container_adaptor/vector_map_adaptor.hpp
/// \brief Container adaptor.
#ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP
#define BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/bimap/container_adaptor/vector_adaptor.hpp>
#include <boost/bimap/container_adaptor/detail/identity_converters.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
namespace bimaps {
namespace container_adaptor {
/// \brief Container adaptor.
template
<
class Base,
class Iterator,
class ConstIterator,
class ReverseIterator,
class ConstReverseIterator,
class IteratorToBaseConverter = ::boost::mpl::na,
class IteratorFromBaseConverter = ::boost::mpl::na,
class ReverseIteratorFromBaseConverter = ::boost::mpl::na,
class ValueToBaseConverter = ::boost::mpl::na,
class ValueFromBaseConverter = ::boost::mpl::na,
class FunctorsFromDerivedClasses = mpl::vector<>
>
class vector_map_adaptor :
public vector_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
>
{
typedef vector_adaptor
<
Base,
Iterator, ConstIterator, ReverseIterator, ConstReverseIterator,
IteratorToBaseConverter, IteratorFromBaseConverter,
ReverseIteratorFromBaseConverter,
ValueToBaseConverter, ValueFromBaseConverter,
FunctorsFromDerivedClasses
> base_;
// MetaData -------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::first_type key_type;
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type::second_type data_type;
// Access -----------------------------------------------------------------
public:
vector_map_adaptor() {}
explicit vector_map_adaptor(Base & c) :
base_(c) {}
protected:
typedef vector_map_adaptor vector_map_adaptor_;
};
} // namespace container_adaptor
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_CONTAINER_ADAPTOR_VECTOR_MAP_ADAPTOR_HPP

View File

@@ -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)
/// \file detail/bimap_core.hpp
/// \brief Bimap base definition.
#ifndef BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP
#define BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
// Boost.MPL
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/is_same.hpp>
// Boost.MultiIndex
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
// Boost.Bimap.Relation
#include <boost/bimap/relation/relation.hpp>
#include <boost/bimap/relation/member_at.hpp>
// Boost.Bimap.Tags
#include <boost/bimap/tags/support/apply_to_value_type.hpp>
// Boost.Bimap
#include <boost/bimap/detail/manage_bimap_key.hpp>
#include <boost/bimap/detail/manage_additional_parameters.hpp>
#include <boost/bimap/detail/map_view_iterator.hpp>
#include <boost/bimap/detail/set_view_iterator.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/unconstrained_set_of.hpp>
namespace boost {
namespace bimaps {
/// \brief Library details
namespace detail {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Type >
struct get_value_type
{
typedef BOOST_DEDUCED_TYPENAME Type::value_type type;
};
struct independent_index_tag {};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/// \brief Base for the bimap class.
/**
See also bimap.
**/
template< class LeftSetType, class RightSetType, class AP1, class AP2, class AP3 >
struct bimap_core
{
// Manage bimap key instantiation
// --------------------------------------------------------------------
private:
typedef BOOST_DEDUCED_TYPENAME manage_bimap_key
<
LeftSetType,
::boost::bimaps::relation::member_at::left
>::type left_tagged_set_type;
typedef BOOST_DEDUCED_TYPENAME manage_bimap_key
<
RightSetType,
::boost::bimaps::relation::member_at::right
>::type right_tagged_set_type;
// Construct the relation type to be used
// --------------------------------------------------------------------
public:
//@{
typedef BOOST_DEDUCED_TYPENAME left_tagged_set_type::value_type left_set_type;
typedef BOOST_DEDUCED_TYPENAME right_tagged_set_type::value_type right_set_type;
//@}
//@{
typedef BOOST_DEDUCED_TYPENAME left_tagged_set_type::tag left_tag;
typedef BOOST_DEDUCED_TYPENAME right_tagged_set_type::tag right_tag;
//@}
//@{
typedef BOOST_DEDUCED_TYPENAME left_set_type::value_type left_key_type;
typedef BOOST_DEDUCED_TYPENAME right_set_type::value_type right_key_type;
//@}
//@{
typedef right_key_type left_data_type;
typedef left_key_type right_data_type;
//@}
// Manage the additional parameters
// --------------------------------------------------------------------
private:
typedef BOOST_DEDUCED_TYPENAME manage_additional_parameters<AP1,AP2,AP3>::type parameters;
/// \brief Relation type stored by the bimap.
// --------------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::select_relation
<
::boost::bimaps::tags::tagged<
BOOST_DEDUCED_TYPENAME mpl::if_<
mpl::and_
<
BOOST_DEDUCED_TYPENAME left_set_type::mutable_key,
BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation::left_mutable_key
>,
// {
left_key_type,
// }
// else
// {
BOOST_DEDUCED_TYPENAME ::boost::add_const< left_key_type >::type
// }
>::type,
left_tag
>,
::boost::bimaps::tags::tagged<
BOOST_DEDUCED_TYPENAME mpl::if_<
mpl::and_
<
BOOST_DEDUCED_TYPENAME right_set_type::mutable_key,
BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation::right_mutable_key
>,
// {
right_key_type,
// }
// else
// {
BOOST_DEDUCED_TYPENAME ::boost::add_const< right_key_type >::type
// }
>::type,
right_tag
>,
// Force mutable keys
true
>::type relation;
//@{
typedef BOOST_DEDUCED_TYPENAME relation::left_pair left_value_type;
typedef BOOST_DEDUCED_TYPENAME relation::right_pair right_value_type;
//@}
// Bind the member of the relation, so multi_index can manage them
// --------------------------------------------------------------------
private:
typedef BOOST_MULTI_INDEX_MEMBER(relation, left_key_type, left)
left_member_extractor;
typedef BOOST_MULTI_INDEX_MEMBER(relation,right_key_type,right)
right_member_extractor;
// The core indices are somewhat complicated to calculate, because they
// can be zero, one, two or three indices, depending on the use of
// {side}_based set type of relations and unconstrained_set_of and
// unconstrained_set_of_relation specifications.
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >,
// {
mpl::vector<>,
// }
// else
// {
mpl::vector
<
BOOST_DEDUCED_TYPENAME left_set_type::
BOOST_NESTED_TEMPLATE index_bind
<
left_member_extractor,
left_tag
>::type
>
// }
>::type left_core_indices;
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >,
// {
left_core_indices,
// }
// else
// {
BOOST_DEDUCED_TYPENAME mpl::push_front
<
left_core_indices,
BOOST_DEDUCED_TYPENAME right_set_type::
BOOST_NESTED_TEMPLATE index_bind
<
right_member_extractor,
right_tag
>::type
>::type
// }
>::type basic_core_indices;
// If it is based either on the left or on the right, then only the side
// indices are needed. But the set type of the relation can be completely
// diferent from the one used for the sides in wich case we have to add yet
// another index to the core.
// TODO
// If all the set types are unsconstrained there must be readable compile
// time error.
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, left_based >,
// {
left_tagged_set_type,
// }
/* else */ BOOST_DEDUCED_TYPENAME mpl::if_<
is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, right_based >,
// {
right_tagged_set_type,
// }
// else
// {
tags::tagged
<
BOOST_DEDUCED_TYPENAME parameters::
set_type_of_relation::BOOST_NESTED_TEMPLATE bind_to
<
relation
>::type,
independent_index_tag
>
// }
>::type
>::type tagged_set_of_relation_type;
protected:
typedef BOOST_DEDUCED_TYPENAME tagged_set_of_relation_type::tag
relation_set_tag;
typedef BOOST_DEDUCED_TYPENAME tagged_set_of_relation_type::value_type
relation_set_type_of;
// Logic tags
// This is a necesary extra level of indirection to allow unconstrained
// sets to be plug in the design. The bimap constructors use this logic
// tags.
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >,
independent_index_tag,
right_tag
>::type,
left_tag
>::type logic_left_tag;
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< right_set_type >,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::is_unconstrained_set_of< left_set_type >,
independent_index_tag,
left_tag
>::type,
right_tag
>::type logic_right_tag;
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
is_same< relation_set_tag, independent_index_tag >,
BOOST_DEDUCED_TYPENAME mpl::if_<
::boost::bimaps::detail::
is_unconstrained_set_of< relation_set_type_of >,
logic_left_tag,
independent_index_tag
>::type,
BOOST_DEDUCED_TYPENAME mpl::if_<
is_same< BOOST_DEDUCED_TYPENAME parameters::set_type_of_relation, left_based >,
logic_left_tag,
logic_right_tag
>::type
>::type logic_relation_set_tag;
private:
typedef BOOST_DEDUCED_TYPENAME mpl::if_<
mpl::and_< is_same< relation_set_tag, independent_index_tag >,
mpl::not_<
::boost::bimaps::detail::
is_unconstrained_set_of< relation_set_type_of >
>
>,
// {
BOOST_DEDUCED_TYPENAME mpl::push_front
<
basic_core_indices,
BOOST_DEDUCED_TYPENAME relation_set_type_of::
BOOST_NESTED_TEMPLATE index_bind
<
multi_index::identity<relation>,
independent_index_tag
>::type
>::type,
// }
// else
// {
basic_core_indices
// }
>::type complete_core_indices;
struct core_indices : public complete_core_indices {};
// Define the core using compute_index_type to translate the
// set type to an multi-index specification
// --------------------------------------------------------------------
public:
typedef multi_index::multi_index_container
<
relation,
core_indices,
BOOST_DEDUCED_TYPENAME parameters::allocator::
BOOST_NESTED_TEMPLATE rebind<relation>::other
> core_type;
// Core metadata
// --------------------------------------------------------------------
public:
typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index::
index<core_type, logic_left_tag>::type left_index;
typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index::
index<core_type,logic_right_tag>::type right_index;
typedef BOOST_DEDUCED_TYPENAME left_index::iterator left_core_iterator;
typedef BOOST_DEDUCED_TYPENAME left_index::const_iterator left_core_const_iterator;
typedef BOOST_DEDUCED_TYPENAME right_index::iterator right_core_iterator;
typedef BOOST_DEDUCED_TYPENAME right_index::const_iterator right_core_const_iterator;
// Map by {side} iterator metadata
// --------------------------------------------------------------------
public:
//@{
typedef ::boost::bimaps::detail::map_view_iterator
<
left_tag,
relation,
left_core_iterator
> left_iterator;
typedef ::boost::bimaps::detail::map_view_iterator
<
right_tag,
relation,
right_core_iterator
> right_iterator;
//@}
//@{
typedef ::boost::bimaps::detail::const_map_view_iterator
<
left_tag,
relation,
left_core_const_iterator
> left_const_iterator;
typedef ::boost::bimaps::detail::const_map_view_iterator
<
right_tag,
relation,
right_core_const_iterator
> right_const_iterator;
//@}
// Relation set view
typedef BOOST_DEDUCED_TYPENAME ::boost::multi_index::index
<
core_type, logic_relation_set_tag
>::type relation_set_core_index;
typedef BOOST_DEDUCED_TYPENAME relation_set_type_of::
BOOST_NESTED_TEMPLATE set_view_bind
<
relation_set_core_index
>::type relation_set;
public:
typedef bimap_core bimap_core_;
};
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_BIMAP_CORE_HPP

View File

@@ -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)
/// \file detail/concept_tags.hpp
/// \brief Bimap tags and concepts
#ifndef BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP
#define BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/bool.hpp>
namespace boost {
namespace bimaps {
namespace detail {
/// \brief Tag of {SetType}_of definition classes
/**
The {SetType}_of classes are derived from this class so it is easy to construct
metafunctions. For example now is easy to create a is_set_type_of metafunction.
**/
struct set_type_of_tag {};
/// \brief Tag of {SetType}_of_relation defition classes
struct set_type_of_relation_tag {};
/// \brief Tag of {Side}_based identifiers
struct side_based_tag : set_type_of_relation_tag {};
} // namespace detail
/** \struct boost::bimaps::left_based
\brief Tag to indicate that the main view will be based on the left side.
This is convenient because the multi-index core will be more efficient.
If possible use this options or the right based one.
See also right_based.
**/
/** \struct boost::bimaps::right_based
\brief Tag to indicate that the main view will be based on the right side.
This is convenient because the multi-index core will be more efficient.
If possible use this options or the right based one.
See also left_based.
**/
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
struct left_based : ::boost::bimaps::detail::side_based_tag
{
// I run into troubles if I do not define bind for side based tags.
// Maybe a more coherent way of binding the relation can be developped.
template< class Relation > struct bind_to { typedef void type; };
typedef mpl::bool_<true> left_mutable_key;
typedef mpl::bool_<true> right_mutable_key;
};
struct right_based : ::boost::bimaps::detail::side_based_tag
{
// I run into troubles if I do not define bind for side based tags.
// Maybe a more coherent way of binding the relation can be developped.
template< class Relation > struct bind_to { typedef void type; };
typedef mpl::bool_<true> left_mutable_key;
typedef mpl::bool_<true> right_mutable_key;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
typedef mpl::_ _relation;
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_CONCEPT_TAGS_HPP

View File

@@ -0,0 +1,36 @@
// 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)
/// \file detail/debug/static_error.hpp
/// \brief Formatted compile time error
#ifndef BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP
#define BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/preprocessor/cat.hpp>
// Easier way to call BOOST_MPL_ASSERT_MSG in class scope to generate
// a static error.
/*===========================================================================*/
#define BOOST_BIMAP_STATIC_ERROR(MESSAGE,VARIABLES) \
struct BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE) {}; \
BOOST_MPL_ASSERT_MSG(false, \
BOOST_PP_CAT(BIMAP_STATIC_ERROR__,MESSAGE), \
VARIABLES)
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_DEBUG_STATIC_ERROR_HPP

View File

@@ -0,0 +1,125 @@
// 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)
/// \file detail/generate_index_binder.hpp
/// \brief Define macros to help building the set type of definitions
#ifndef BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP
#define BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/multi_index/tag.hpp>
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP( \
\
MULTI_INDEX_TYPE \
\
) \
\
template< class KeyExtractor, class Tag > \
struct index_bind \
{ \
typedef MULTI_INDEX_TYPE \
< \
multi_index::tag< Tag >, \
KeyExtractor \
\
> type; \
};
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_INDEX_BINDER_1CP( \
\
MULTI_INDEX_TYPE, \
CONFIG_PARAMETER \
\
) \
\
template< class KeyExtractor, class Tag > \
struct index_bind \
{ \
typedef MULTI_INDEX_TYPE \
< \
multi_index::tag< Tag >, \
KeyExtractor, \
CONFIG_PARAMETER \
\
> type; \
};
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_INDEX_BINDER_2CP( \
\
MULTI_INDEX_TYPE, \
CONFIG_PARAMETER_1, \
CONFIG_PARAMETER_2 \
) \
\
template< class KeyExtractor, class Tag > \
struct index_bind \
{ \
typedef MULTI_INDEX_TYPE \
< \
multi_index::tag< Tag >, \
KeyExtractor, \
CONFIG_PARAMETER_1, \
CONFIG_PARAMETER_2 \
\
> type; \
\
};
/*===========================================================================*/
// This is a special registration to allow sequenced and random access indices
// to play along smoothly with the other index types.
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP_NO_EXTRACTOR( \
\
MULTI_INDEX_TYPE \
\
) \
\
template< class KeyExtractor, class Tag > \
struct index_bind \
{ \
typedef MULTI_INDEX_TYPE< multi_index::tag< Tag > > type; \
};
/*===========================================================================*/
// This is yet another special registration to allow unconstrained sets
// to play along smoothly with the other index types.
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_INDEX_BINDER_FAKE \
\
template< class KeyExtractor, class Tag > \
struct index_bind \
{ \
typedef void type; \
}; \
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_GENERATE_INDEX_BINDER_HPP

View File

@@ -0,0 +1,85 @@
// 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)
/// \file detail/generate_relation_binder.hpp
/// \brief Define macros to help building the set type of definitions
#ifndef BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP
#define BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/apply.hpp>
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP( \
\
SET_TYPE_OF \
) \
\
template< class Relation > \
struct bind_to \
{ \
typedef SET_TYPE_OF<Relation> type; \
\
};
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_RELATION_BINDER_1CP( \
\
SET_TYPE_OF, \
CP1 \
) \
\
template< class Relation > \
struct bind_to \
{ \
typedef SET_TYPE_OF \
< \
Relation, \
BOOST_DEDUCED_TYPENAME mpl::apply<CP1,Relation>::type \
\
> type; \
\
};
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_RELATION_BINDER_2CP( \
\
SET_TYPE_OF, \
CP1, \
CP2 \
) \
\
template< class Relation > \
struct bind_to \
{ \
typedef SET_TYPE_OF \
< \
Relation, \
BOOST_DEDUCED_TYPENAME mpl::apply<CP1,Relation>::type, \
BOOST_DEDUCED_TYPENAME mpl::apply<CP2,Relation>::type \
\
> type; \
\
};
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_GENERATE_RELATION_BINDER_HPP

View File

@@ -0,0 +1,58 @@
// 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)
/// \file detail/generate_view_binder.hpp
/// \brief Define macros to help building the set type of definitions
#ifndef BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP
#define BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/multi_index/tag.hpp>
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( \
\
MAP_VIEW_TYPE \
\
) \
\
template< class Tag, class BimapType > \
struct map_view_bind \
{ \
typedef MAP_VIEW_TYPE \
< \
Tag, \
BimapType \
\
> type; \
};
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( \
\
SET_VIEW_TYPE \
\
) \
\
template< class IndexType > \
struct set_view_bind \
{ \
typedef SET_VIEW_TYPE<IndexType> type; \
};
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_GENERATE_VIEW_BINDER_HPP

View File

@@ -0,0 +1,66 @@
// 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)
/// \file detail/is_set_type_of.hpp
/// \brief Is set type of and is set type of relation metafunctions.
#ifndef BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP
#define BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/bimap/detail/concept_tags.hpp>
/** \struct boost::bimaps::detail::is_set_type_of
\brief Type trait to check if a class is a set_type_of specification
\code
template< class Type >
struct is_set_type_of : {true_|false_} {};
\endcode
**/
/** \struct boost::bimaps::detail::is_set_type_of_relation
\brief Type trait to check if a class is a set_type_of_relation specification
\code
template< class Type >
struct is_set_type_of_relation : {true_|false_} {};
\endcode
**/
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
namespace boost {
namespace bimaps {
namespace detail {
template< class Type >
struct is_set_type_of :
is_base_of< set_type_of_tag, Type > {};
template< class Type >
struct is_set_type_of_relation :
is_base_of< set_type_of_relation_tag, Type > {};
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
#endif // BOOST_BIMAP_DETAIL_IS_SET_TYPE_OF_HPP

View File

@@ -0,0 +1,225 @@
// 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)
/// \file detail/manage_additional_parameters.hpp
/// \brief Utility class to extract the additional parameters from the template parameters.
#ifndef BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP
#define BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <memory>
// Boost.MPL
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/aux_/na.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/bimap/detail/is_set_type_of.hpp>
namespace boost {
namespace bimaps {
namespace detail {
/// \brief Metafunction to check if a given type is a data_hook specification.
template< class Type >
struct is_data_hook : ::boost::mpl::false_ {};
/** \struct boost::bimaps::detail::manage_additional_parameters
\brief Utility class to extract the additional parameters from the template parameters.
\code
template< class AP1, class AP2, class AP3 >
struct manage_additional_parameters
{
struct parameters
{
typedef -unspecified- set_type_of_relation;
typedef -unspecified- data_hook;
typedef -unspecified- allocator;
};
typedef parameters type;
};
\endcode
See also bimap, bimap_core.
**/
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class AP1, class AP2, class AP3 >
struct manage_additional_parameters
{
// (1) manage_additional_parameters<
// not_specified,not_specified,not_specified>
//
// set_type_of_relation: based on the left key type
// hook_data: no additional data
// allocator: default allocator
struct case_NNN
{
typedef left_based set_type_of_relation;
typedef std::allocator<void> allocator;
};
// (2) manage_additional_parameters<Allocator,not_specified,not_specified>
//
// set_type_of_relation: based on the left key type
// hook_data: no additional data
// allocator: Allocator
struct case_ANN
{
typedef left_based set_type_of_relation;
typedef AP1 allocator;
};
// (3) manage_additional_parameters<
// SetOfRelationType,not_specified,not_specified>
//
// set_type_of_relation: SetTypeOfRelation
// hook_data: no additional data
// allocator: default allocator
struct case_SNN
{
typedef AP1 set_type_of_relation;
typedef std::allocator<void> allocator;
};
// (4) manage_additional_parameters<
// SetTypeOfRelation,Allocator,not_specified>
//
// set_type_of_relation: SetTypeOfRelation
// hook_data: no additional data
// allocator: Allocator
struct case_SAN
{
typedef AP1 set_type_of_relation;
typedef AP2 allocator;
};
// (5) manage_additional_parameters<DataToHook,not_specified,not_specified>
//
// set_type_of_relation: based on the left key type
// hook_data: DataToHook
// allocator: default allocator
struct case_HNN
{
typedef left_based set_type_of_relation;
typedef std::allocator<void> allocator;
};
// (6) manage_additional_parameters<
// SetTypeOfRelation,DataToHook,not_specified>
//
// set_type_of_relation: SetTypeOfRelation
// hook_data: DataToHook
// allocator: default allocator
struct case_SHN
{
typedef AP1 set_type_of_relation;
typedef std::allocator<void> allocator;
};
// (7) manage_additional_parameters<
// DataToHook,Allocator,not_specified>
//
// set_type_of_relation: SetTypeOfRelation
// hook_data: DataToHook
// allocator: default allocator
struct case_HAN
{
typedef left_based set_type_of_relation;
typedef AP2 allocator;
};
// (8) manage_additional_parameters<
// SetTypeOfRelation,DataToHook,Allocator>
//
// set_type_of_relation: SetTypeOfRelation
// hook_data: DataToHook
// allocator: Allocator
struct case_SHA
{
typedef AP1 set_type_of_relation;
typedef AP2 allocator;
};
// Some annidated mpl::if_ and we are done!
typedef BOOST_DEDUCED_TYPENAME mpl::if_
<
::boost::mpl::is_na<AP1>,
case_NNN, // (1)
BOOST_DEDUCED_TYPENAME mpl::if_
<
::boost::mpl::is_na<AP2>,
BOOST_DEDUCED_TYPENAME mpl::if_
<
is_set_type_of_relation<AP1>,
case_SNN, // (3)
BOOST_DEDUCED_TYPENAME mpl::if_
<
is_data_hook<AP1>,
case_HNN, // (5)
case_ANN // (2)
>::type
>::type,
BOOST_DEDUCED_TYPENAME mpl::if_
<
::boost::mpl::is_na<AP3>,
BOOST_DEDUCED_TYPENAME mpl::if_
<
is_data_hook<AP1>,
case_HAN, // (7)
BOOST_DEDUCED_TYPENAME mpl::if_
<
is_data_hook<AP2>,
case_SHN, // (6)
case_SAN // (4)
>::type
>::type,
case_SHA // (8)
>::type
>::type
>::type type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_MANAGE_ADDITIONAL_PARAMETERS_HPP

View File

@@ -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)
/// \file detail/manage_bimap_key.hpp
/// \brief Utility class to manage the set types of a bimap.
#ifndef BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP
#define BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
// Boost.Bimap.Tags
#include <boost/bimap/tags/support/default_tagged.hpp>
#include <boost/bimap/tags/support/apply_to_value_type.hpp>
// Boost.MPL
#include <boost/mpl/if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/bimap/detail/is_set_type_of.hpp>
#include <boost/bimap/set_of.hpp>
namespace boost {
namespace bimaps {
namespace detail {
/** \struct boost::bimaps::detail::manage_bimap_key
\brief Metafunction to manage the set types of a bimap.
\code
template< class SetType, class DefaultTag >
struct manage_bimap_key
{
typedef {TaggedSetType} type;
}
\endcode
If KeyType is not tagged, DefaultTag is used. If KeyType is not a SetOfType
specification it is converted to set_of< value_type_of<KeyType>::type > and the
it is tagged with his tag or the default one.
See also bimap, bimap_core.
**/
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class SetType, class DefaultTag >
struct manage_bimap_key
{
// First, convert the type to a tagged one with the default tag
typedef BOOST_DEDUCED_TYPENAME tags::support::default_tagged
<
SetType, DefaultTag
>::type tagged_set_type;
// Then manage plain key types, were the set type of the collection
// is not specified in the instantiation
typedef BOOST_DEDUCED_TYPENAME
mpl::if_< BOOST_DEDUCED_TYPENAME is_set_type_of<
BOOST_DEDUCED_TYPENAME tagged_set_type::value_type >::type,
// {
// The type is
tagged_set_type,
// }
// else
// {
// Default it to a set
BOOST_DEDUCED_TYPENAME tags::support::apply_to_value_type
<
set_of< mpl::_ >,
tagged_set_type
>::type
// }
>::type type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_MANAGE_BIMAP_KEY_HPP

View File

@@ -0,0 +1,545 @@
// 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)
/// \file detail/map_view_base.hpp
/// \brief Helper base for the construction of the bimap views types.
#ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
#define BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <stdexcept>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/bimap/relation/support/get_pair_functor.hpp>
#include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp>
#include <boost/bimap/container_adaptor/support/iterator_facade_converters.hpp>
#include <boost/bimap/relation/support/data_extractor.hpp>
#include <boost/bimap/relation/support/opposite_tag.hpp>
#include <boost/bimap/relation/support/pair_type_by.hpp>
#include <boost/bimap/support/iterator_type_by.hpp>
#include <boost/bimap/support/key_type_by.hpp>
#include <boost/bimap/support/data_type_by.hpp>
#include <boost/bimap/support/value_type_by.hpp>
#include <boost/bimap/detail/modifier_adaptor.hpp>
#include <boost/bimap/detail/debug/static_error.hpp>
namespace boost {
namespace bimaps {
namespace detail {
// The next macro can be converted in a metafunctor to gain code robustness.
/*===========================================================================*/
#define BOOST_BIMAP_MAP_VIEW_CONTAINER_ADAPTOR( \
CONTAINER_ADAPTOR, TAG,BIMAP, OTHER_ITER, CONST_OTHER_ITER \
) \
::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \
< \
BOOST_DEDUCED_TYPENAME BIMAP::core_type:: \
BOOST_NESTED_TEMPLATE index<TAG>::type, \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
iterator_type_by<TAG,BIMAP>::type, \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
const_iterator_type_by<TAG,BIMAP>::type, \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
OTHER_ITER<TAG,BIMAP>::type, \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
CONST_OTHER_ITER<TAG,BIMAP>::type, \
::boost::bimaps::container_adaptor::support::iterator_facade_to_base \
< \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
iterator_type_by<TAG,BIMAP>::type, \
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support:: \
const_iterator_type_by<TAG,BIMAP>::type \
\
>, \
::boost::mpl::na, \
::boost::mpl::na, \
::boost::bimaps::relation::detail:: \
pair_to_relation_functor<TAG,BOOST_DEDUCED_TYPENAME BIMAP::relation>, \
::boost::bimaps::relation::support:: \
get_pair_functor<TAG, BOOST_DEDUCED_TYPENAME BIMAP::relation > \
>
/*===========================================================================*/
#if defined(BOOST_MSVC)
/*===========================================================================*/
#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \
typedef ::boost::bimaps::detail::map_view_base< \
TYPE<TAG,BIMAP>,TAG,BIMAP > friend_map_view_base; \
friend class friend_map_view_base;
/*===========================================================================*/
#else
/*===========================================================================*/
#define BOOST_BIMAP_MAP_VIEW_BASE_FRIEND(TYPE,TAG,BIMAP) \
friend class ::boost::bimaps::detail::map_view_base< \
TYPE<TAG,BIMAP>,TAG,BIMAP >;
/*===========================================================================*/
#endif
/// \brief Common base for map views.
template< class Derived, class Tag, class BimapType>
class map_view_base
{
typedef ::boost::bimaps::container_adaptor::support::
iterator_facade_to_base<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
iterator_type_by<Tag,BimapType>::type,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
const_iterator_type_by<Tag,BimapType>::type
> iterator_to_base_;
typedef ::boost::bimaps::relation::detail::
pair_to_relation_functor<Tag,
BOOST_DEDUCED_TYPENAME BimapType::relation> value_to_base_;
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
key_type_by<Tag,BimapType>::type key_type_;
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
data_type_by<Tag,BimapType>::type data_type_;
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
pair_type_by<Tag,
BOOST_DEDUCED_TYPENAME BimapType::relation>::type value_type_;
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
iterator_type_by<Tag,BimapType>::type iterator_;
public:
bool replace(iterator_ position, const value_type_ & x)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),
derived().template functor<value_to_base_>()(x)
);
}
template< class CompatibleKey >
bool replace_key(iterator_ position, const CompatibleKey & k)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),
derived().template functor<value_to_base_>()(
value_type_(k,position->second)
)
);
}
template< class CompatibleData >
bool replace_data(iterator_ position, const CompatibleData & d)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),
derived().template functor<value_to_base_>()(
value_type_(position->first,d)
)
);
}
/* This function may be provided in the future
template< class Modifier >
bool modify(iterator_ position, Modifier mod)
{
return derived().base().modify(
derived().template functor<iterator_to_base_>()(position),
::boost::bimaps::detail::relation_modifier_adaptor
<
Modifier,
BOOST_DEDUCED_TYPENAME BimapType::relation,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
Tag, BOOST_DEDUCED_TYPENAME BimapType::relation
>::type,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
opossite_tag<Tag,BimapType>::type,
BOOST_DEDUCED_TYPENAME BimapType::relation
>::type
>(mod)
);
}
*/
template< class Modifier >
bool modify_key(iterator_ position, Modifier mod)
{
return derived().base().modify_key(
derived().template functor<iterator_to_base_>()(position), mod
);
}
template< class Modifier >
bool modify_data(iterator_ position, Modifier mod)
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
opossite_tag<Tag,BimapType>::type,
BOOST_DEDUCED_TYPENAME BimapType::relation
>::type data_extractor_;
return derived().base().modify(
derived().template functor<iterator_to_base_>()(position),
// this may be replaced later by
// ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
::boost::bimaps::detail::unary_modifier_adaptor
<
Modifier,
BOOST_DEDUCED_TYPENAME BimapType::relation,
data_extractor_
>(mod)
);
}
protected:
typedef map_view_base map_view_base_;
private:
// Curiously Recurring Template interface.
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
template< class Derived, class Tag, class BimapType>
class mutable_data_unique_map_view_access
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
data_type_by<Tag,BimapType>::type data_type_;
public:
template< class CompatibleKey >
data_type_ & at(const CompatibleKey& k)
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
iterator_type_by<Tag,BimapType>::type iterator;
iterator iter = derived().find(k);
if( iter == derived().end() )
{
::boost::throw_exception(
std::out_of_range("bimap<>: invalid key")
);
}
return iter->second;
}
template< class CompatibleKey >
const data_type_ & at(const CompatibleKey& k) const
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
const_iterator_type_by<Tag,BimapType>::type const_iterator;
const_iterator iter = derived().find(k);
if( iter == derived().end() )
{
::boost::throw_exception(
std::out_of_range("bimap<>: invalid key")
);
}
return iter->second;
}
template< class CompatibleKey >
data_type_ & operator[](const CompatibleKey& k)
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
iterator_type_by<Tag,BimapType>::type iterator;
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
value_type_by<Tag,BimapType>::type value_type;
iterator iter = derived().find(k);
if( iter == derived().end() )
{
iter = derived().insert( value_type(k,data_type_()) ).first;
}
return iter->second;
}
protected:
typedef mutable_data_unique_map_view_access
mutable_data_unique_map_view_access_;
private:
// Curiously Recurring Template interface.
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
template< class Derived, class Tag, class BimapType>
class non_mutable_data_unique_map_view_access
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
data_type_by<Tag,BimapType>::type data_type_;
public:
template< class CompatibleKey >
const data_type_ & at(const CompatibleKey& k) const
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
const_iterator_type_by<Tag,BimapType>::type const_iterator;
const_iterator iter = derived().find(k);
if( iter == derived().end() )
{
::boost::throw_exception(
std::out_of_range("bimap<>: invalid key")
);
}
return iter->second;
}
template< class CompatibleKey >
data_type_ & operator[](const CompatibleKey& k)
{
BOOST_BIMAP_STATIC_ERROR( OPERATOR_BRACKET_IS_NOT_SUPPORTED, (Derived));
}
protected:
typedef non_mutable_data_unique_map_view_access
non_mutable_data_unique_map_view_access_;
private:
// Curiously Recurring Template interface.
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
template< class Derived, class Tag, class BimapType>
struct unique_map_view_access
{
private:
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::
value_type_by<Tag,BimapType>::type value_type;
public:
typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_
<
typename ::boost::is_const<
BOOST_DEDUCED_TYPENAME value_type::second_type >::type,
non_mutable_data_unique_map_view_access<Derived,Tag,BimapType>,
mutable_data_unique_map_view_access<Derived,Tag,BimapType>
>::type type;
};
} // namespace detail
// This function is already part of Boost.Lambda.
// They may be moved to Boost.Utility.
template <class T> inline const T& make_const(const T& t) { return t; }
} // namespace bimaps
} // namespace boost
// The following macros avoids code duplication in map views
// Maybe this can be changed in the future using a scheme similar to
// the one used with map_view_base.
/*===========================================================================*/
#define BOOST_BIMAP_MAP_VIEW_RANGE_IMPLEMENTATION(BASE) \
\
template< class LowerBounder, class UpperBounder> \
std::pair<BOOST_DEDUCED_TYPENAME BASE::iterator, \
BOOST_DEDUCED_TYPENAME BASE::iterator> \
range(LowerBounder lower,UpperBounder upper) \
{ \
std::pair< \
\
BOOST_DEDUCED_TYPENAME BASE::base_type::iterator, \
BOOST_DEDUCED_TYPENAME BASE::base_type::iterator \
\
> r( this->base().range(lower,upper) ); \
\
return std::pair \
< \
BOOST_DEDUCED_TYPENAME BASE::iterator, \
BOOST_DEDUCED_TYPENAME BASE::iterator \
>( \
this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
>() ( r.first ), \
this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
>() ( r.second ) \
); \
} \
\
template< class LowerBounder, class UpperBounder> \
std::pair<BOOST_DEDUCED_TYPENAME BASE::const_iterator, \
BOOST_DEDUCED_TYPENAME BASE::const_iterator> \
range(LowerBounder lower,UpperBounder upper) const \
{ \
std::pair< \
\
BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator, \
BOOST_DEDUCED_TYPENAME BASE::base_type::const_iterator \
\
> r( this->base().range(lower,upper) ); \
\
return std::pair \
< \
BOOST_DEDUCED_TYPENAME BASE::const_iterator, \
BOOST_DEDUCED_TYPENAME BASE::const_iterator \
>( \
this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
>() ( r.first ), \
this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::iterator_from_base \
>() ( r.second ) \
); \
}
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_VIEW_ASSIGN_IMPLEMENTATION(BASE) \
\
template< class InputIterator > \
void assign(InputIterator first,InputIterator last) \
{ \
this->clear(); \
this->insert(this->end(),first,last); \
} \
\
void assign(BOOST_DEDUCED_TYPENAME BASE::size_type n, \
const BOOST_DEDUCED_TYPENAME BASE::value_type& v) \
{ \
this->clear(); \
for(BOOST_DEDUCED_TYPENAME BASE::size_type i = 0 ; i < n ; ++n) \
{ \
this->push_back(v); \
} \
}
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_VIEW_FRONT_BACK_IMPLEMENTATION(BASE) \
\
BOOST_DEDUCED_TYPENAME BASE::reference front() \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_from_base>() \
( \
const_cast \
< \
BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \
\
> ( this->base().front() ) \
); \
} \
\
BOOST_DEDUCED_TYPENAME BASE::reference back() \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_from_base>() \
( \
const_cast \
< \
BOOST_DEDUCED_TYPENAME BASE::base_type::value_type & \
\
>( this->base().back() ) \
); \
} \
\
BOOST_DEDUCED_TYPENAME BASE::const_reference front() const \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \
( \
this->base().front() \
); \
} \
\
BOOST_DEDUCED_TYPENAME BASE::const_reference back() const \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME BASE::value_from_base>() \
( \
this->base().back() \
); \
}
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_BASE_HPP

View File

@@ -0,0 +1,237 @@
// 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)
/// \file detail/map_view_iterator.hpp
/// \brief Iterator adaptors from multi-index to bimap.
#ifndef BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP
#define BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
// Boost
#include <boost/serialization/nvp.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/bimap/relation/support/pair_by.hpp>
namespace boost {
namespace bimaps {
namespace detail {
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Tag, class Relation, class CoreIterator > struct map_view_iterator;
template< class Tag, class Relation, class CoreIterator >
struct map_view_iterator_base
{
typedef iterator_adaptor
<
map_view_iterator< Tag, Relation, CoreIterator >,
CoreIterator,
BOOST_DEDUCED_TYPENAME remove_reference
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
pair_reference_type_by<Tag,Relation>::type
>::type,
::boost::use_default,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
pair_reference_type_by<Tag,Relation>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/** \brief Map View Iterator adaptor from multi index to bimap.
This is class is based on transform iterator from Boost.Iterator that is
modified to allow serialization. It has been specialized for this
library, and EBO optimization was applied to the functor.
**/
template< class Tag, class Relation, class CoreIterator >
struct map_view_iterator : public map_view_iterator_base<Tag,Relation,CoreIterator>::type
{
typedef BOOST_DEDUCED_TYPENAME
map_view_iterator_base<Tag,Relation,CoreIterator>::type base_;
public:
// The best way will be to pass the correct "value_type" to
// iterator_adaptor and to set the "pointer" to Reference*, but
// iterator_adaptor and iterator_facade defines "pointer" as value_type*
// and do not allow this to be changed.
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::pair_type_by
<
Tag, Relation
>::type value_type;
map_view_iterator() {}
map_view_iterator(CoreIterator const& iter)
: base_(iter) {}
map_view_iterator(map_view_iterator const & iter)
: base_(iter.base()) {}
BOOST_DEDUCED_TYPENAME base_::reference dereference() const
{
return ::boost::bimaps::relation::support::pair_by<Tag>(
*const_cast<BOOST_DEDUCED_TYPENAME base_::base_type::value_type*>(
&(*this->base())
)
);
}
private:
friend class iterator_core_access;
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
// Serialization support
BOOST_SERIALIZATION_SPLIT_MEMBER();
friend class ::boost::serialization::access;
template< class Archive >
void save(Archive & ar, const unsigned int version) const
{
ar << ::boost::serialization::make_nvp("mi_iterator",this->base());
}
template< class Archive >
void load(Archive & ar, const unsigned int version)
{
CoreIterator iter;
ar >> ::boost::serialization::make_nvp("mi_iterator",iter);
this->base_reference() = iter;
}
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class Tag, class Relation, class CoreIterator > struct const_map_view_iterator;
template< class Tag, class Relation, class CoreIterator >
struct const_map_view_iterator_base
{
typedef iterator_adaptor
<
const_map_view_iterator< Tag, Relation, CoreIterator >,
CoreIterator,
BOOST_DEDUCED_TYPENAME remove_reference
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
const_pair_reference_type_by<Tag,Relation>::type
>::type,
::boost::use_default,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
const_pair_reference_type_by<Tag,Relation>::type
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/** \brief Const Map View Iterator adaptor from multi index to bimap.
See also map_view_iterator.
**/
template< class Tag, class Relation, class CoreIterator >
struct const_map_view_iterator :
public const_map_view_iterator_base<Tag,Relation,CoreIterator>::type
{
typedef BOOST_DEDUCED_TYPENAME
const_map_view_iterator_base<Tag,Relation,CoreIterator>::type base_;
public:
// The best way will be to pass the correct "value_type" to
// iterator_adaptor and to set the "pointer" to Reference*, but
// iterator_adaptor and iterator_facade defines "pointer" as
// value_type* and do not allow this to be changed.
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::pair_type_by
<
Tag, Relation
>::type value_type;
const_map_view_iterator() {}
const_map_view_iterator(CoreIterator const& iter)
: base_(iter) {}
const_map_view_iterator(const_map_view_iterator const & iter)
: base_(iter.base()) {}
const_map_view_iterator(map_view_iterator<Tag,Relation,CoreIterator> i)
: base_(i.base()) {}
BOOST_DEDUCED_TYPENAME base_::reference dereference() const
{
return ::boost::bimaps::relation::support::pair_by<Tag>(*this->base());
}
private:
friend class iterator_core_access;
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
// Serialization support
BOOST_SERIALIZATION_SPLIT_MEMBER();
friend class ::boost::serialization::access;
template< class Archive >
void save(Archive & ar, const unsigned int version) const
{
ar << ::boost::serialization::make_nvp("mi_iterator",this->base());
}
template< class Archive >
void load(Archive & ar, const unsigned int version)
{
CoreIterator iter;
ar >> ::boost::serialization::make_nvp("mi_iterator",iter);
this->base_reference() = iter;
}
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP

View File

@@ -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)
/// \file detail/modifier_adaptor.hpp
/// \brief A binary to unary functor relation modifier adaptor.
#ifndef BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP
#define BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <functional>
namespace boost {
namespace bimaps {
namespace detail {
/// \brief A binary to unary functor relation modifier adaptor.
template
<
class Modifier,
class NewArgument,
class FirstExtractor,
class SecondExtractor
>
struct relation_modifier_adaptor :
public std::unary_function<NewArgument,bool>,
Modifier,
FirstExtractor,
SecondExtractor
{
relation_modifier_adaptor( const Modifier & m ) : Modifier(m) {}
relation_modifier_adaptor( const Modifier & m,
const FirstExtractor & fe,
const SecondExtractor & se ) :
Modifier(m), FirstExtractor(fe), SecondExtractor(se) {}
void operator()( NewArgument & x ) const
{
Modifier::operator()(
FirstExtractor ::operator()( x ),
SecondExtractor::operator()( x )
);
}
};
/// \brief A simple unary modifier adaptor.
// This modifier is equivalent to bind( Modifier, bind( Extractor, _1 ) )
// It may be a good idea to start using Boost.Bind instead of it.
template
<
class Modifier,
class NewArgument,
class Extractor
>
struct unary_modifier_adaptor :
public std::unary_function<NewArgument,bool>,
Modifier,
Extractor
{
unary_modifier_adaptor( const Modifier & m ) : Modifier(m) {}
unary_modifier_adaptor( const Modifier & m,
const Extractor & fe) :
Modifier(m), Extractor(fe) {}
void operator()( NewArgument & x ) const
{
Modifier::operator()( Extractor::operator()( x ) );
}
};
} // namespace detail
} // namespace bimap
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_MODIFIER_ADAPTOR_HPP

View File

@@ -0,0 +1,71 @@
// 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)
/// \file detail/non_unique_views_helper.hpp
/// \brief Details for non unique views
#ifndef BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP
#define BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
/*===========================================================================*/
#define BOOST_BIMAP_NON_UNIQUE_VIEW_INSERT_FUNCTIONS \
\
template <class InputIterator> \
void insert(InputIterator iterBegin, InputIterator iterEnd) \
{ \
for( ; iterBegin != iterEnd ; ++iterBegin ) \
{ \
this->base().insert( \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_to_base>()( \
BOOST_DEDUCED_TYPENAME base_::value_type(*iterBegin)) ); \
} \
} \
\
std::pair<BOOST_DEDUCED_TYPENAME base_::iterator, bool> insert( \
BOOST_DEDUCED_TYPENAME ::boost::call_traits< \
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \
{ \
typedef BOOST_DEDUCED_TYPENAME base_::base_type::iterator base_iterator; \
\
std::pair< base_iterator, bool > r( \
this->base().insert( \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x) ) \
); \
\
return std::pair<typename base_::iterator, bool>( \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()(r.first), \
r.second \
); \
} \
\
BOOST_DEDUCED_TYPENAME base_::iterator insert( \
BOOST_DEDUCED_TYPENAME base_::iterator pos, \
BOOST_DEDUCED_TYPENAME ::boost::call_traits< \
BOOST_DEDUCED_TYPENAME base_::value_type >::param_type x) \
{ \
return this->template functor< \
BOOST_DEDUCED_TYPENAME base_::iterator_from_base>()( \
this->base().insert( \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::iterator_to_base>()(pos), \
this->template functor< \
BOOST_DEDUCED_TYPENAME base_::value_to_base>()(x)) \
); \
}
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_NON_UNIQUE_VIEWS_HELPER_HPP

View File

@@ -0,0 +1,328 @@
// 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)
/// \file detail/set_view_base.hpp
/// \brief Helper base for the construction of the bimap views types.
#ifndef BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP
#define BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/relation/member_at.hpp>
#include <boost/bimap/relation/support/data_extractor.hpp>
#include <boost/bimap/detail/modifier_adaptor.hpp>
#include <boost/bimap/detail/set_view_iterator.hpp>
#include <boost/bimap/relation/support/get_pair_functor.hpp>
#include <boost/bimap/relation/detail/to_mutable_relation_functor.hpp>
namespace boost {
namespace bimaps {
namespace detail {
// This helper functor can be eliminated if the we do not
// have to support the standard relation
template< class Key, class Value, class KeyToBase >
class forced_extractor
{
public:
const Key operator()( const Value & v ) const
{
return keyToBase( v );
}
private:
KeyToBase keyToBase;
};
template< class Key, class KeyToBase >
class forced_extractor<Key,Key,KeyToBase>
{
public:
const Key & operator()( const Key & k ) const
{
return k;
}
};
// The next macro can be converted in a metafunctor to gain code robustness.
/*===========================================================================*/
#define BOOST_BIMAP_SET_VIEW_CONTAINER_ADAPTOR( \
CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER \
) \
::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \
< \
CORE_INDEX, \
::boost::bimaps::detail:: \
set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >, \
::boost::bimaps::container_adaptor::support::iterator_facade_to_base \
< \
::boost::bimaps::detail:: set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>, \
::boost::bimaps::detail::const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator> \
\
>, \
::boost::mpl::na, \
::boost::mpl::na, \
::boost::bimaps::relation::detail:: \
get_mutable_relation_functor< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \
::boost::bimaps::relation::support:: \
get_above_view_functor< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \
::boost::bimaps::detail::forced_extractor< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::key_type, \
BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type, \
BOOST_DEDUCED_TYPENAME CORE_INDEX::key_from_value \
> \
>
/*===========================================================================*/
/*===========================================================================*/
#define BOOST_BIMAP_SEQUENCED_SET_VIEW_CONTAINER_ADAPTOR( \
CONTAINER_ADAPTOR, CORE_INDEX, OTHER_ITER, CONST_OTHER_ITER \
) \
::boost::bimaps::container_adaptor::CONTAINER_ADAPTOR \
< \
CORE_INDEX, \
::boost::bimaps::detail:: \
set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::OTHER_ITER >, \
::boost::bimaps::detail:: \
const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::CONST_OTHER_ITER >, \
::boost::bimaps::container_adaptor::support::iterator_facade_to_base \
< \
::boost::bimaps::detail:: set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::iterator>, \
::boost::bimaps::detail::const_set_view_iterator< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::const_iterator> \
\
>, \
::boost::mpl::na, \
::boost::mpl::na, \
::boost::bimaps::relation::detail:: \
get_mutable_relation_functor< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type >, \
::boost::bimaps::relation::support:: \
get_above_view_functor< \
BOOST_DEDUCED_TYPENAME CORE_INDEX::value_type > \
>
/*===========================================================================*/
#if defined(BOOST_MSVC)
/*===========================================================================*/
#define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE) \
typedef ::boost::bimaps::detail::set_view_base< \
TYPE< INDEX_TYPE >, INDEX_TYPE > template_class_friend; \
friend class template_class_friend;
/*===========================================================================*/
#else
/*===========================================================================*/
#define BOOST_BIMAP_SET_VIEW_BASE_FRIEND(TYPE,INDEX_TYPE) \
friend class ::boost::bimaps::detail::set_view_base< \
TYPE< INDEX_TYPE >, INDEX_TYPE >;
/*===========================================================================*/
#endif
/// \brief Common base for set views.
template< class Derived, class Index >
class set_view_base
{
typedef ::boost::bimaps::container_adaptor::support::
iterator_facade_to_base
<
::boost::bimaps::detail::
set_view_iterator<BOOST_DEDUCED_TYPENAME Index:: iterator>,
::boost::bimaps::detail::
const_set_view_iterator<BOOST_DEDUCED_TYPENAME Index::const_iterator>
> iterator_to_base_;
typedef BOOST_DEDUCED_TYPENAME Index::value_type::left_value_type left_type_;
typedef BOOST_DEDUCED_TYPENAME Index::value_type::right_value_type right_type_;
typedef BOOST_DEDUCED_TYPENAME Index::value_type value_type_;
typedef ::boost::bimaps::detail::
set_view_iterator<BOOST_DEDUCED_TYPENAME Index::iterator> iterator_;
public:
bool replace(iterator_ position,
const value_type_ & x)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),x
);
}
template< class CompatibleLeftType >
bool replace_left(iterator_ position,
const CompatibleLeftType & l)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),
value_type_(l,position->right)
);
}
template< class CompatibleRightType >
bool replace_right(iterator_ position,
const CompatibleRightType & r)
{
return derived().base().replace(
derived().template functor<iterator_to_base_>()(position),
value_type_(position->left,r)
);
}
/* This function may be provided in the future
template< class Modifier >
bool modify(iterator_ position,
Modifier mod)
{
return derived().base().modify(
derived().template functor<iterator_to_base_>()(position),
::boost::bimaps::detail::relation_modifier_adaptor
<
Modifier,
BOOST_DEDUCED_TYPENAME Index::value_type,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
::boost::bimaps::relation::member_at::left,
BOOST_DEDUCED_TYPENAME Index::value_type
>::type,
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
::boost::bimaps::relation::member_at::right,
BOOST_DEDUCED_TYPENAME Index::value_type
>::type
>(mod)
);
}
*/
/*
template< class Modifier >
bool modify_left(iterator_ position, Modifier mod)
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right,
BOOST_DEDUCED_TYPENAME Index::value_type
>::type left_data_extractor_;
return derived().base().modify(
derived().template functor<iterator_to_base_>()(position),
// this may be replaced later by
// ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
::boost::bimaps::detail::unary_modifier_adaptor
<
Modifier,
BOOST_DEDUCED_TYPENAME Index::value_type,
left_data_extractor_
>(mod)
);
}
template< class Modifier >
bool modify_right(iterator_ position, Modifier mod)
{
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
data_extractor
<
BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::member_at::right,
BOOST_DEDUCED_TYPENAME Index::value_type
>::type right_data_extractor_;
return derived().base().modify(
derived().template functor<iterator_to_base_>()(position),
// this may be replaced later by
// ::boost::bind( mod, ::boost::bind(data_extractor_(),_1) )
::boost::bimaps::detail::unary_modifier_adaptor
<
Modifier,
BOOST_DEDUCED_TYPENAME Index::value_type,
right_data_extractor_
>(mod)
);
}
*/
protected:
typedef set_view_base set_view_base_;
private:
// Curiously Recurring Template interface.
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_SET_VIEW_BASE_HPP

View File

@@ -0,0 +1,220 @@
// 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)
/// \file detail/set_view_iterator.hpp
/// \brief Iterator adaptors from multi-index to bimap.
#ifndef BOOST_BIMAP_DETAIL_SET_VIEW_ITERATOR_HPP
#define BOOST_BIMAP_DETAIL_SET_VIEW_ITERATOR_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
// Boost
#include <boost/serialization/nvp.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/bimap/relation/support/get_pair_functor.hpp>
namespace boost {
namespace bimaps {
namespace detail {
/** \brief Set View Iterator adaptor from multi index to bimap.
This is class is based on transform iterator from Boost.Iterator that is
modified to allow serialization. It has been specialized for this
library, and EBO optimization was applied to the functor.
**/
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class CoreIterator > struct set_view_iterator;
template< class CoreIterator >
struct set_view_iterator_base
{
typedef iterator_adaptor
<
set_view_iterator< CoreIterator >,
CoreIterator,
BOOST_DEDUCED_TYPENAME remove_reference
<
BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view_reference
>::type,
::boost::use_default,
BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view_reference
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class CoreIterator >
struct set_view_iterator : public set_view_iterator_base<CoreIterator>::type
{
typedef BOOST_DEDUCED_TYPENAME set_view_iterator_base<CoreIterator>::type base_;
public:
// The best way will be to pass the correct "value_type" to
// iterator_adaptor and to set the "pointer" to Reference*, but
// iterator_adaptor and iterator_facade defines "pointer" as
// value_type* and do not allow this to be changed.
typedef BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view value_type;
set_view_iterator() {}
set_view_iterator(CoreIterator const& iter)
: base_(iter) {}
set_view_iterator(set_view_iterator const & iter)
: base_(iter.base()) {}
typename base_::reference dereference() const
{
return const_cast<
BOOST_DEDUCED_TYPENAME base_::base_type::value_type*>(
&(*this->base())
)->get_view();
}
private:
friend class iterator_core_access;
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
// Serialization support
BOOST_SERIALIZATION_SPLIT_MEMBER();
friend class ::boost::serialization::access;
template< class Archive >
void save(Archive & ar, const unsigned int version) const
{
ar << ::boost::serialization::make_nvp("mi_iterator",this->base());
}
template< class Archive >
void load(Archive & ar, const unsigned int version)
{
CoreIterator iter;
ar >> ::boost::serialization::make_nvp("mi_iterator",iter);
this->base_reference() = iter;
}
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
template< class CoreIterator > struct const_set_view_iterator;
template< class CoreIterator >
struct const_set_view_iterator_base
{
typedef iterator_adaptor
<
set_view_iterator< CoreIterator >,
CoreIterator,
BOOST_DEDUCED_TYPENAME remove_reference
<
BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view_reference
>::type,
::boost::use_default,
BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view_reference
> type;
};
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
/** \brief Const Set View Iterator adaptor from multi index to bimap.
See also set_view_iterator.
**/
template< class CoreIterator >
struct const_set_view_iterator : public const_set_view_iterator_base<CoreIterator>::type
{
typedef BOOST_DEDUCED_TYPENAME const_set_view_iterator_base<CoreIterator>::type base_;
public:
// The best way will be to pass the correct "value_type" to
// iterator_adaptor and to set the "pointer" to Reference*, but
// iterator_adaptor and iterator_facade defines "pointer" as value_type*
// and do not allow this to be changed.
typedef BOOST_DEDUCED_TYPENAME CoreIterator::value_type::above_view value_type;
const_set_view_iterator() {}
const_set_view_iterator(CoreIterator const& iter)
: base_(iter) {}
const_set_view_iterator(const_set_view_iterator const & iter)
: base_(iter.base()) {}
const_set_view_iterator(set_view_iterator<CoreIterator> i)
: base_(i.base()) {}
BOOST_DEDUCED_TYPENAME base_::reference dereference() const
{
return this->base()->get_view();
}
private:
friend class iterator_core_access;
#ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
// Serialization support
BOOST_SERIALIZATION_SPLIT_MEMBER();
friend class ::boost::serialization::access;
template< class Archive >
void save(Archive & ar, const unsigned int version) const
{
ar << ::boost::serialization::make_nvp("mi_iterator",this->base());
}
template< class Archive >
void load(Archive & ar, const unsigned int version)
{
CoreIterator iter;
ar >> ::boost::serialization::make_nvp("mi_iterator",iter);
this->base_reference() = iter;
}
#endif // BOOST_BIMAP_DISABLE_SERIALIZATION
};
} // namespace detail
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_DETAIL_MAP_VIEW_ITERATOR_HPP

View File

@@ -0,0 +1,113 @@
// 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_DETAIL_CHECK_METADATA_HPP
#define BOOST_BIMAP_DETAIL_CHECK_METADATA_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/cat.hpp>
// Easier way to call BOOST_MPL_ASSERT_MSG in class scope
/*===========================================================================*/
#define BOOST_BIMAP_MPL_ASSERT_MSG_ACS(p1,p2,p3) \
\
struct p2 {}; \
BOOST_MPL_ASSERT_MSG(p1,p2,p3); \
/*===========================================================================*/
// Build a descriptive name.
/*===========================================================================*/
#define BOOST_BIMAP_WRONG_METADATA_MESSAGE( \
\
P_CLASS, \
P_NAME, \
P_CORRECT_TYPE \
\
) \
\
BOOST_PP_CAT \
( \
WRONG_METADATA__, \
BOOST_PP_CAT \
( \
P_CLASS, \
BOOST_PP_CAT \
( \
__AT__, \
BOOST_PP_CAT \
( \
P_NAME, \
BOOST_PP_CAT \
( \
__IS_DIFERENT_TO__, \
P_CORRECT_TYPE \
) \
) \
) \
) \
)
/*===========================================================================*/
// Check if the metadata have the correct type, and if not inform
// it with a useful compile time message.
/*===========================================================================*/
#define BOOST_BIMAP_CHECK_METADATA( \
\
P_CLASS, \
P_NAME, \
P_CORRECT_TYPE \
\
) \
\
BOOST_BIMAP_MPL_ASSERT_MSG_ACS \
( \
( \
::boost::is_same \
< \
P_CLASS::P_NAME, \
P_CORRECT_TYPE \
\
>::value \
), \
BOOST_BIMAP_WRONG_METADATA_MESSAGE \
( \
P_CLASS, \
P_NAME, \
P_CORRECT_TYPE \
), \
(P_CLASS::P_NAME,P_CORRECT_TYPE) \
)
/*===========================================================================*/
// Just for autodocumment the test code
/*===========================================================================*/
#define BOOST_BIMAP_TEST_STATIC_FUNCTION(NAME) \
namespace NAME
/*===========================================================================*/
// Just for autodocument the test code
/*===========================================================================*/
#define BOOST_BIMAP_CALL_TEST_STATIC_FUNCTION(NAME)
/*===========================================================================*/
#endif // BOOST_BIMAP_DETAIL_CHECK_METADATA_HPP

View File

@@ -0,0 +1,24 @@
// 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)
/// \file detail/user_interface_config.hpp
/// \brief General configuration directives
#ifndef BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP
#define BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#ifdef BOOST_BIMAP_DISABLE_SERIALIZATION
#define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
#endif
#endif // BOOST_BIMAP_DETAIL_USER_INTERFACE_CONFIG_HPP

164
include/boost/bimap/list_of.hpp Executable file
View File

@@ -0,0 +1,164 @@
// 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)
/// \file list_of.hpp
/// \brief Include support for list constrains for the bimap container
#ifndef BOOST_BIMAP_LIST_OF_HPP
#define BOOST_BIMAP_LIST_OF_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/detail/user_interface_config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/bimap/detail/concept_tags.hpp>
#include <boost/bimap/detail/generate_index_binder.hpp>
#include <boost/bimap/detail/generate_view_binder.hpp>
#include <boost/bimap/detail/generate_relation_binder.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/bimap/views/list_map_view.hpp>
#include <boost/bimap/views/list_set_view.hpp>
namespace boost {
namespace bimaps {
/// \brief Set Type Specification
/**
This struct is used to specify a set specification.
It is not a container, it is just a metaprogramming facility to
express the type of a set. Generally, this specification will
be used in other place to create a container.
It has the same syntax that an std::list instantiation, except
that the allocator cannot be specified. The rationale behind
this difference is that the allocator is not part of the set
type specification, rather it is a container configuration
parameter.
\code
using namespace support;
BOOST_STATIC_ASSERT( is_set_type_of< list_of<Type> >::value );
BOOST_STATIC_ASSERT
(
is_same
<
list_of<Type>::index_bind
<
KeyExtractor,
Tag
>::type,
sequenced< tag<Tag>, KeyExtractor >
>::value
);
typedef bimap
<
list_of<Type>, RightKeyType
> bimap_with_left_type_as_list;
BOOST_STATIC_ASSERT
(
is_same
<
list_of<Type>::map_view_bind
<
member_at::left,
bimap_with_left_type_as_list
>::type,
list_map_view< member_at::left, bimap_with_left_type_as_list >
>::value
);
\endcode
See also list_of_relation.
**/
template< class Type >
struct list_of : public ::boost::bimaps::detail::set_type_of_tag
{
/// Type of the object that will be stored in the list
typedef Type value_type;
BOOST_BIMAP_GENERATE_INDEX_BINDER_0CP_NO_EXTRACTOR(
// binds to
multi_index::sequenced
);
BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER(
// binds to
views::list_map_view
);
BOOST_BIMAP_GENERATE_SET_VIEW_BINDER(
// binds to
views::list_set_view
);
typedef mpl::bool_<true> mutable_key;
};
/// \brief List Of Relation Specification
/**
This struct is similar to list_of but it is bind logically to a
relation. It is used in the bimap instantiation to specify the
desired type of the main view. This struct implements internally
a metafunction named bind_to that manages the quite complicated
task of finding the right type of the set for the relation.
\code
template<class Relation>
struct bind_to
{
typedef -unspecified- type;
};
\endcode
See also list_of, is_set_type_of_relation.
**/
struct list_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag
{
BOOST_BIMAP_GENERATE_RELATION_BINDER_0CP(
// binds to
list_of
);
typedef mpl::bool_<true> left_mutable_key;
typedef mpl::bool_<true> right_mutable_key;
};
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_LIST_OF_HPP

View File

@@ -0,0 +1,186 @@
// 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)
/// \file multiset_of.hpp
/// \brief Include support for multiset constrains for the bimap container
#ifndef BOOST_BIMAP_MULTISET_OF_HPP
#define BOOST_BIMAP_MULTISET_OF_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/detail/user_interface_config.hpp>
#include <functional>
#include <boost/mpl/bool.hpp>
#include <boost/bimap/detail/concept_tags.hpp>
#include <boost/bimap/detail/generate_index_binder.hpp>
#include <boost/bimap/detail/generate_view_binder.hpp>
#include <boost/bimap/detail/generate_relation_binder.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/bimap/views/multimap_view.hpp>
#include <boost/bimap/views/multiset_view.hpp>
namespace boost {
namespace bimaps {
/// \brief Set Type Specification
/**
This struct is used to specify a multiset specification.
It is not a container, it is just a metaprogramming facility to
express the type of a set. Generally, this specification will
be used in other place to create a container.
It has the same syntax that an std::set instantiation, except
that the allocator cannot be specified. The rationale behind
this difference is that the allocator is not part of the set
type specification, rather it is a container configuration
parameter.
The first parameter is the type of the objects in the multiset,
and the second one is a Functor that compares them.
Bimap binding metafunctions can be used with this class in
the following way:
\code
using namespace support;
BOOST_STATIC_ASSERT( is_set_type_of< multiset_of<Type> >::value );
BOOST_STATIC_ASSERT
(
is_same
<
compute_index_type
<
multiset_of<Type,KeyCompare>,
KeyExtractor,
Tag
>::type
,
ordered_nonunique< tag<Tag>, KeyExtractor, KeyCompare >
>::value
);
typedef bimap
<
multiset_of<Type>, RightKeyType
> bimap_with_left_type_as_multiset;
BOOST_STATIC_ASSERT
(
is_same
<
compute_map_view_type
<
member_at::left,
bimap_with_left_type_as_multiset
>::type,
multimap_view< member_at::left, bimap_with_left_type_as_multiset >
>::value
);
\endcode
See also multiset_of_relation.
**/
template
<
class KeyType,
class KeyCompare = std::less< KeyType >
>
struct multiset_of : public ::boost::bimaps::detail::set_type_of_tag
{
/// Type of the object that will be stored in the set
typedef KeyType value_type;
/// Functor that compare two keys
typedef KeyCompare key_compare;
BOOST_BIMAP_GENERATE_INDEX_BINDER_1CP(
// binds to
multi_index::ordered_non_unique,
// with
key_compare
);
BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER(
// binds to
views::multimap_view
);
BOOST_BIMAP_GENERATE_SET_VIEW_BINDER(
// binds to
views::multiset_view
);
typedef mpl::bool_<false> mutable_key;
};
/// \brief Set Of Relation Specification
/**
This struct is similar to multiset_of but it is bind logically to a
relation. It is used in the bimap instantiation to specify the
desired type of the main view. This struct implements internally
a metafunction named bind_to that manages the quite complicated
task of finding the right type of the set for the relation.
\code
template<class Relation>
struct bind_to
{
typedef -unspecified- type;
};
\endcode
See also multiset_of, is_set_type_of_relation.
**/
template< class KeyCompare = std::less< _relation > >
struct multiset_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag
{
/// Functor that compare two keys
typedef KeyCompare key_compare;
BOOST_BIMAP_GENERATE_RELATION_BINDER_1CP(
// binds to
multiset_of,
// with
key_compare
);
typedef mpl::bool_<false> left_mutable_key;
typedef mpl::bool_<false> right_mutable_key;
};
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_MULTISET_OF_HPP

View File

@@ -0,0 +1,55 @@
// 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)
/// \file property_map/set_support.hpp
/// \brief Support for the property map concept.
#ifndef BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP
#define BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/property_map.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/support/data_type_by.hpp>
#include <boost/bimap/support/key_type_by.hpp>
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
namespace boost {
template< class Tag, class Bimap >
struct property_traits< ::boost::bimaps::views::map_view<Tag,Bimap> >
{
typedef BOOST_DEDUCED_TYPENAME
::boost::bimaps::support::data_type_by<Tag,Bimap>::type value_type;
typedef BOOST_DEDUCED_TYPENAME
::boost::bimaps::support:: key_type_by<Tag,Bimap>::type key_type;
typedef readable_property_map_tag category;
};
template< class Tag, class Bimap >
const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::data_type_by<Tag,Bimap>::type &
get(const ::boost::bimaps::views::map_view<Tag,Bimap> & m,
const BOOST_DEDUCED_TYPENAME
::boost::bimaps::support::key_type_by<Tag,Bimap>::type & key)
{
return m.at(key);
}
} // namespace boost
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
#endif // BOOST_BIMAP_PROPERTY_MAP_SET_SUPPORT_HPP

View File

@@ -0,0 +1,55 @@
// 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)
/// \file property_map/unordered_set_support.hpp
/// \brief Support for the property map concept.
#ifndef BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP
#define BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/property_map.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/support/data_type_by.hpp>
#include <boost/bimap/support/key_type_by.hpp>
#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
namespace boost {
template< class Tag, class Bimap >
struct property_traits< ::boost::bimaps::views::unordered_map_view<Tag,Bimap> >
{
typedef BOOST_DEDUCED_TYPENAME
::boost::bimaps::support::data_type_by<Tag,Bimap>::type value_type;
typedef BOOST_DEDUCED_TYPENAME
::boost::bimaps::support:: key_type_by<Tag,Bimap>::type key_type;
typedef readable_property_map_tag category;
};
template< class Tag, class Bimap >
const BOOST_DEDUCED_TYPENAME ::boost::bimaps::support::data_type_by<Tag,Bimap>::type &
get(const ::boost::bimaps::views::unordered_map_view<Tag,Bimap> & m,
const BOOST_DEDUCED_TYPENAME
::boost::bimaps::support::key_type_by<Tag,Bimap>::type & key)
{
return m.at(key);
}
} // namespace boost
#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
#endif // BOOST_BIMAP_PROPERTY_MAP_UNORDERED_SET_SUPPORT_HPP

View File

@@ -0,0 +1,170 @@
// 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)
/// \file relation/detail/access_builder.hpp
/// \brief Define macros to help building metafunctions
#ifndef BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP
#define BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/relation/support/member_with_tag.hpp>
#include <boost/bimap/relation/member_at.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
/******************************************************************************
BIMAP SYMMETRIC ACCESS RESULT OF
*******************************************************************************
namespace result_of {
template< class Tag, class SymmetricType >
struct NAME
{
typedef -unspecified- type;
};
} // namespace result_of
******************************************************************************/
/*===========================================================================*/
#define BOOST_BIMAP_SYMMETRIC_ACCESS_RESULT_OF_BUILDER( \
\
NAME, \
METAFUNCTION_BASE \
) \
\
namespace result_of { \
\
template< class Tag, class SymmetricType > \
struct NAME \
{ \
typedef BOOST_DEDUCED_TYPENAME METAFUNCTION_BASE \
< \
Tag,SymmetricType \
\
>::type value_type; \
\
typedef BOOST_DEDUCED_TYPENAME mpl::if_< is_const<SymmetricType>, \
\
BOOST_DEDUCED_TYPENAME call_traits<value_type>::const_reference, \
\
BOOST_DEDUCED_TYPENAME call_traits<value_type>::reference \
\
>::type type; \
}; \
\
}
/*===========================================================================*/
/******************************************************************************
BIMAP SYMMETRIC ACCESS IMPLEMENTATION
*******************************************************************************
namespace detail {
template< class Tag, class SymmetricType >
typename result_of::NAME<Tag,SymmetricType>::type
NAME( Tag , const Relation & );
} // namespace detail
******************************************************************************/
/*===========================================================================*/
#define BOOST_BIMAP_SYMMETRIC_ACCESS_IMPLEMENTATION_BUILDER( \
\
NAME, \
TP_SYMMETRIC, \
PARAMETER_NAME, \
LEFT_BODY, \
RIGHT_BODY \
) \
\
namespace detail { \
\
\
\
template< class TP_SYMMETRIC > \
BOOST_DEDUCED_TYPENAME result_of::NAME \
< \
::boost::bimaps::relation::member_at::left,TP_SYMMETRIC \
\
>::type \
\
NAME( ::boost::bimaps::relation::member_at::left, \
TP_SYMMETRIC & PARAMETER_NAME ) \
{ \
LEFT_BODY; \
} \
\
template< class TP_SYMMETRIC > \
BOOST_DEDUCED_TYPENAME result_of::NAME \
< \
::boost::bimaps::relation::member_at::right,TP_SYMMETRIC \
\
>::type \
\
NAME( ::boost::bimaps::relation::member_at::right, \
TP_SYMMETRIC & PARAMETER_NAME ) \
{ \
RIGHT_BODY; \
} \
\
}
/*===========================================================================*/
/******************************************************************************
BIMAP RELATION ACCESS INTERFACE
*******************************************************************************
template< class Tag, class SymmetricType >
typename result_of::NAME<Tag,SymmetricType>::type
NAME( const SymmetricType & );
******************************************************************************/
/*===========================================================================*/
#define BOOST_BIMAP_SYMMETRIC_ACCESS_INTERFACE_BUILDER( \
\
NAME \
) \
\
template< class Tag, class SymmetricType > \
BOOST_DEDUCED_TYPENAME result_of::NAME<Tag,SymmetricType>::type \
NAME( SymmetricType & s ) \
{ \
typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: \
member_with_tag \
< \
Tag,SymmetricType \
\
>::type member_at_tag; \
\
return detail::NAME(member_at_tag(),s); \
}
/*===========================================================================*/
#endif // BOOST_BIMAP_RELATION_ACCESS_BUILDER_HPP

View File

@@ -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)
/// \file relation/detail/metadata_access_builder.hpp
/// \brief Define macros to help building metafunctions
#ifndef BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCESS_BUILDER_HPP
#define BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCESS_BUILDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/relation/support/is_tag_of_member_at.hpp>
#include <boost/bimap/detail/debug/static_error.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/preprocessor/cat.hpp>
/******************************************************************************
BIMAP SYMMETRIC METADATA ACCESS INTERFACE
*******************************************************************************
template< class Tag, class SymmetricType >
struct NAME
{
typedef -unspecified- type;
};
******************************************************************************/
/*===========================================================================*/
#define BOOST_BIMAP_SYMMETRIC_METADATA_ACCESS_BUILDER( \
\
NAME, \
METADATA_BY_LEFT, \
METADATA_BY_RIGHT \
) \
\
template \
< \
class Tag, \
class SymmetricType, \
class Enable = void \
> \
struct NAME \
{ \
BOOST_BIMAP_STATIC_ERROR( \
BOOST_PP_CAT(NAME,_FAILURE), \
(SymmetricType,Tag) \
); \
}; \
\
template< class Tag, class SymmetricType > \
struct NAME \
< \
Tag, SymmetricType, \
BOOST_DEDUCED_TYPENAME enable_if \
< \
::boost::bimaps::relation::support::is_tag_of_member_at_left \
< \
Tag, \
SymmetricType \
> \
\
>::type \
> \
{ \
typedef BOOST_DEDUCED_TYPENAME SymmetricType::METADATA_BY_LEFT type; \
}; \
\
template< class Tag, class SymmetricType > \
struct NAME \
< \
Tag, SymmetricType, \
BOOST_DEDUCED_TYPENAME enable_if \
< \
::boost::bimaps::relation::support::is_tag_of_member_at_right \
< \
Tag, \
SymmetricType \
> \
\
>::type \
> \
{ \
typedef BOOST_DEDUCED_TYPENAME SymmetricType::METADATA_BY_RIGHT type; \
};
/*===========================================================================*/
#endif // BOOST_BIMAP_RELATION_DETAIL_METADATA_ACCES_BUILDER_HPP

View File

@@ -0,0 +1,83 @@
// 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)
/// \file relation/detail/mutant.hpp
/// \brief Mutate functions to extract views of mutant classes.
#ifndef BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP
#define BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/detail/debug/static_error.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost {
namespace bimaps {
namespace relation {
/// \brief Relation details, mutant idiom and symmetrical metafunctions builders.
namespace detail {
//@{
/// \brief Converts a mutant class to a view with zero overhead.
/**
This function is a safe wrapper around reinterpret_cast. It checks at
compile time that the desired view is supported by the mutant class.
See also mutant, can_mutate_in.
\ingroup mutant_group
**/
template< class View, class Type >
BOOST_DEDUCED_TYPENAME enable_if< mpl::not_< is_const< Type > >,
View&
>::type mutate( Type & m )
{
BOOST_MPL_ASSERT((
::boost::mpl::contains<BOOST_DEDUCED_TYPENAME Type::mutant_views,View>
));
return *reinterpret_cast< View* >(addressof(m));
}
template< class View, class Type >
BOOST_DEDUCED_TYPENAME enable_if< is_const< Type >,
const View&
>::type mutate( Type & m )
{
BOOST_MPL_ASSERT((
::boost::mpl::contains<BOOST_DEDUCED_TYPENAME Type::mutant_views,View>
));
return *reinterpret_cast< const View* >(addressof(m));
}
//@}
} // namespace detail
} // namespace relation
} // namespace bimaps
} // namespace boost
#endif // BOOST_BIMAP_RELATION_DETAIL_MUTANT_HPP

View File

@@ -0,0 +1,105 @@
// 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)
/// \file relation/detail/static_access_builder.hpp
/// \brief Define macros to help building metafunctions
#ifndef BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCESS_BUILDER_HPP
#define BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCESS_BUILDER_HPP
#if defined(_MSC_VER) && (_MSC_VER>=1200)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/bimap/relation/support/is_tag_of_member_at.hpp>
#include <boost/bimap/detail/debug/static_error.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/preprocessor/cat.hpp>
/******************************************************************************
BIMAP SYMMETRIC STATIC ACCESS INTERFACE
*******************************************************************************
template< class Tag, class SYMETRIC_TYPE >
struct NAME
{
-UNDEFINED BODY-;
};
******************************************************************************/
/*===========================================================================*/
#define BOOST_BIMAP_SYMMETRIC_STATIC_ACCESS_BUILDER( \
\
NAME, \
SYMMETRIC_TYPE, \
LEFT_BODY, \
RIGHT_BODY \
) \
\
template \
< \
class Tag, \
class SYMMETRIC_TYPE, \
class Enable = void \
> \
struct NAME \
{ \
BOOST_BIMAP_STATIC_ERROR( \
BOOST_PP_CAT(NAME,_FAILURE), \
(SYMMETRIC_TYPE,Tag) \
); \
}; \
\
template< class Tag, class SYMMETRIC_TYPE > \
struct NAME \
< \
Tag, SYMMETRIC_TYPE, \
BOOST_DEDUCED_TYPENAME enable_if \
< \
::boost::bimaps::relation::support::is_tag_of_member_at_left \
< \
Tag, \
SYMMETRIC_TYPE \
> \
\
>::type \
> \
{ \
LEFT_BODY; \
}; \
\
template< class Tag, class SYMMETRIC_TYPE > \
struct NAME \
< \
Tag, SYMMETRIC_TYPE, \
BOOST_DEDUCED_TYPENAME enable_if \
< \
::boost::bimaps::relation::support::is_tag_of_member_at_right \
< \
Tag, \
SYMMETRIC_TYPE \
> \
\
>::type \
> \
{ \
RIGHT_BODY; \
};
/*===========================================================================*/
#endif // BOOST_BIMAP_RELATION_DETAIL_STATIC_ACCES_BUILDER_HPP

Some files were not shown because too many files have changed in this diff Show More