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:
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal 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
75
doc/acknowledgements.qbk
Executable 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
237
doc/bimap.hdf
Executable 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
164
doc/bimap.qbk
Executable 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
385
doc/bimap_and_boost.qbk
Executable 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
54
doc/compiler_specifics.qbk
Executable 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
13
doc/directdoxygen.jam
Normal 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
220
doc/examples.qbk
Executable 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
48
doc/future_work.qbk
Executable 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
450
doc/history.qbk
Executable 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
99
doc/introduction.qbk
Executable 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
60
doc/jamfile.v2
Executable 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
19
doc/performance.qbk
Executable 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
177
doc/quick_tutorial.qbk
Executable 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
908
doc/rationale.qbk
Executable 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
64
doc/reference.qbk
Executable 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
528
doc/reference/bimap.qbk
Executable 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
796
doc/reference/list_of.qbk
Executable 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
906
doc/reference/set_of.qbk
Executable 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]
|
||||
123
doc/reference/unconstrained_set_of.qbk
Executable file
123
doc/reference/unconstrained_set_of.qbk
Executable 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]
|
||||
|
||||
|
||||
824
doc/reference/unordered_set_of.qbk
Executable file
824
doc/reference/unordered_set_of.qbk
Executable 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
841
doc/reference/vector_of.qbk
Executable 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
19
doc/release_notes.qbk
Executable 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
110
doc/test_suite.qbk
Executable 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
75
doc/toolbox.qbk
Executable 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
937
doc/tutorial.qbk
Executable 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
46
example/Jamfile.v2
Executable 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 ]
|
||||
;
|
||||
97
example/at_function_examples.cpp
Executable file
97
example/at_function_examples.cpp
Executable 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;
|
||||
}
|
||||
|
||||
79
example/bimap_and_boost/assign.cpp
Executable file
79
example/bimap_and_boost/assign.cpp
Executable 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;
|
||||
}
|
||||
49
example/bimap_and_boost/lambda.cpp
Executable file
49
example/bimap_and_boost/lambda.cpp
Executable 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;
|
||||
}
|
||||
|
||||
|
||||
59
example/bimap_and_boost/property_map.cpp
Executable file
59
example/bimap_and_boost/property_map.cpp
Executable 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
122
example/bimap_and_boost/range.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
|
||||
89
example/bimap_and_boost/serialization.cpp
Executable file
89
example/bimap_and_boost/serialization.cpp
Executable 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;
|
||||
}
|
||||
|
||||
87
example/mi_to_b_path/bidirectional_map.cpp
Executable file
87
example/mi_to_b_path/bidirectional_map.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
99
example/mi_to_b_path/hashed_indices.cpp
Executable file
99
example/mi_to_b_path/hashed_indices.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
107
example/mi_to_b_path/mi_bidirectional_map.cpp
Executable file
107
example/mi_to_b_path/mi_bidirectional_map.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
100
example/mi_to_b_path/mi_hashed_indices.cpp
Executable file
100
example/mi_to_b_path/mi_hashed_indices.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
90
example/mi_to_b_path/tagged_bidirectional_map.cpp
Executable file
90
example/mi_to_b_path/tagged_bidirectional_map.cpp
Executable 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
109
example/mighty_bimap.cpp
Executable 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
75
example/population_bimap.cpp
Executable 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
60
example/projection.cpp
Executable 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
91
example/repetitions_counter.cpp
Executable 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
82
example/simple_bimap.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
|
||||
93
example/standard_map_comparison.cpp
Executable file
93
example/standard_map_comparison.cpp
Executable 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
102
example/step_by_step.cpp
Executable 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
86
example/tagged_simple_bimap.cpp
Executable 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;
|
||||
}
|
||||
//]
|
||||
|
||||
118
example/tutorial_modify_and_replace.cpp
Executable file
118
example/tutorial_modify_and_replace.cpp
Executable 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
97
example/tutorial_range.cpp
Executable 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;
|
||||
}
|
||||
|
||||
|
||||
94
example/unconstrained_collection.cpp
Executable file
94
example/unconstrained_collection.cpp
Executable 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
142
example/user_defined_names.cpp
Executable 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
18
include/boost/bimap.hpp
Normal 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
433
include/boost/bimap/bimap.hpp
Executable 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
|
||||
289
include/boost/bimap/container_adaptor/associative_container_adaptor.hpp
Executable file
289
include/boost/bimap/container_adaptor/associative_container_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
|
||||
286
include/boost/bimap/container_adaptor/container_adaptor.hpp
Executable file
286
include/boost/bimap/container_adaptor/container_adaptor.hpp
Executable 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
|
||||
101
include/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp
Executable file
101
include/boost/bimap/container_adaptor/detail/comparison_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
98
include/boost/bimap/container_adaptor/detail/functor_bag.hpp
Executable file
98
include/boost/bimap/container_adaptor/detail/functor_bag.hpp
Executable 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
|
||||
|
||||
|
||||
191
include/boost/bimap/container_adaptor/detail/identity_converters.hpp
Executable file
191
include/boost/bimap/container_adaptor/detail/identity_converters.hpp
Executable 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
|
||||
|
||||
|
||||
45
include/boost/bimap/container_adaptor/detail/key_extractor.hpp
Executable file
45
include/boost/bimap/container_adaptor/detail/key_extractor.hpp
Executable 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
|
||||
|
||||
|
||||
62
include/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp
Executable file
62
include/boost/bimap/container_adaptor/detail/non_unique_container_helper.hpp
Executable 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
|
||||
|
||||
|
||||
249
include/boost/bimap/container_adaptor/list_adaptor.hpp
Executable file
249
include/boost/bimap/container_adaptor/list_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
282
include/boost/bimap/container_adaptor/list_map_adaptor.hpp
Executable file
282
include/boost/bimap/container_adaptor/list_map_adaptor.hpp
Executable 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
|
||||
|
||||
131
include/boost/bimap/container_adaptor/map_adaptor.hpp
Executable file
131
include/boost/bimap/container_adaptor/map_adaptor.hpp
Executable 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
|
||||
|
||||
109
include/boost/bimap/container_adaptor/multimap_adaptor.hpp
Executable file
109
include/boost/bimap/container_adaptor/multimap_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
103
include/boost/bimap/container_adaptor/multiset_adaptor.hpp
Executable file
103
include/boost/bimap/container_adaptor/multiset_adaptor.hpp
Executable 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
|
||||
|
||||
312
include/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp
Executable file
312
include/boost/bimap/container_adaptor/ordered_associative_container_adaptor.hpp
Executable 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
|
||||
355
include/boost/bimap/container_adaptor/sequence_container_adaptor.hpp
Executable file
355
include/boost/bimap/container_adaptor/sequence_container_adaptor.hpp
Executable 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
|
||||
100
include/boost/bimap/container_adaptor/set_adaptor.hpp
Executable file
100
include/boost/bimap/container_adaptor/set_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
77
include/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp
Executable file
77
include/boost/bimap/container_adaptor/support/iterator_facade_converters.hpp
Executable 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
|
||||
@@ -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
|
||||
132
include/boost/bimap/container_adaptor/unordered_map_adaptor.hpp
Executable file
132
include/boost/bimap/container_adaptor/unordered_map_adaptor.hpp
Executable 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
|
||||
|
||||
110
include/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp
Executable file
110
include/boost/bimap/container_adaptor/unordered_multimap_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
102
include/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp
Executable file
102
include/boost/bimap/container_adaptor/unordered_multiset_adaptor.hpp
Executable 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
|
||||
|
||||
98
include/boost/bimap/container_adaptor/unordered_set_adaptor.hpp
Executable file
98
include/boost/bimap/container_adaptor/unordered_set_adaptor.hpp
Executable 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
|
||||
|
||||
142
include/boost/bimap/container_adaptor/vector_adaptor.hpp
Executable file
142
include/boost/bimap/container_adaptor/vector_adaptor.hpp
Executable 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
|
||||
|
||||
|
||||
103
include/boost/bimap/container_adaptor/vector_map_adaptor.hpp
Executable file
103
include/boost/bimap/container_adaptor/vector_map_adaptor.hpp
Executable 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
|
||||
|
||||
488
include/boost/bimap/detail/bimap_core.hpp
Executable file
488
include/boost/bimap/detail/bimap_core.hpp
Executable 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
|
||||
97
include/boost/bimap/detail/concept_tags.hpp
Executable file
97
include/boost/bimap/detail/concept_tags.hpp
Executable 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
|
||||
|
||||
36
include/boost/bimap/detail/debug/static_error.hpp
Executable file
36
include/boost/bimap/detail/debug/static_error.hpp
Executable 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
|
||||
125
include/boost/bimap/detail/generate_index_binder.hpp
Executable file
125
include/boost/bimap/detail/generate_index_binder.hpp
Executable 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
|
||||
85
include/boost/bimap/detail/generate_relation_binder.hpp
Executable file
85
include/boost/bimap/detail/generate_relation_binder.hpp
Executable 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
|
||||
58
include/boost/bimap/detail/generate_view_binder.hpp
Executable file
58
include/boost/bimap/detail/generate_view_binder.hpp
Executable 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
|
||||
66
include/boost/bimap/detail/is_set_type_of.hpp
Executable file
66
include/boost/bimap/detail/is_set_type_of.hpp
Executable 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
|
||||
|
||||
225
include/boost/bimap/detail/manage_additional_parameters.hpp
Executable file
225
include/boost/bimap/detail/manage_additional_parameters.hpp
Executable 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
|
||||
|
||||
103
include/boost/bimap/detail/manage_bimap_key.hpp
Executable file
103
include/boost/bimap/detail/manage_bimap_key.hpp
Executable 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
|
||||
|
||||
|
||||
545
include/boost/bimap/detail/map_view_base.hpp
Executable file
545
include/boost/bimap/detail/map_view_base.hpp
Executable 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
|
||||
237
include/boost/bimap/detail/map_view_iterator.hpp
Executable file
237
include/boost/bimap/detail/map_view_iterator.hpp
Executable 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
|
||||
|
||||
|
||||
89
include/boost/bimap/detail/modifier_adaptor.hpp
Executable file
89
include/boost/bimap/detail/modifier_adaptor.hpp
Executable 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
|
||||
71
include/boost/bimap/detail/non_unique_views_helper.hpp
Executable file
71
include/boost/bimap/detail/non_unique_views_helper.hpp
Executable 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
|
||||
328
include/boost/bimap/detail/set_view_base.hpp
Executable file
328
include/boost/bimap/detail/set_view_base.hpp
Executable 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
|
||||
220
include/boost/bimap/detail/set_view_iterator.hpp
Executable file
220
include/boost/bimap/detail/set_view_iterator.hpp
Executable 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
|
||||
|
||||
|
||||
113
include/boost/bimap/detail/test/check_metadata.hpp
Executable file
113
include/boost/bimap/detail/test/check_metadata.hpp
Executable 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
|
||||
|
||||
24
include/boost/bimap/detail/user_interface_config.hpp
Executable file
24
include/boost/bimap/detail/user_interface_config.hpp
Executable 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
164
include/boost/bimap/list_of.hpp
Executable 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
|
||||
|
||||
186
include/boost/bimap/multiset_of.hpp
Executable file
186
include/boost/bimap/multiset_of.hpp
Executable 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
|
||||
55
include/boost/bimap/property_map/set_support.hpp
Executable file
55
include/boost/bimap/property_map/set_support.hpp
Executable 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
|
||||
55
include/boost/bimap/property_map/unordered_set_support.hpp
Executable file
55
include/boost/bimap/property_map/unordered_set_support.hpp
Executable 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
|
||||
170
include/boost/bimap/relation/detail/access_builder.hpp
Executable file
170
include/boost/bimap/relation/detail/access_builder.hpp
Executable 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
|
||||
|
||||
103
include/boost/bimap/relation/detail/metadata_access_builder.hpp
Executable file
103
include/boost/bimap/relation/detail/metadata_access_builder.hpp
Executable 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
|
||||
|
||||
|
||||
83
include/boost/bimap/relation/detail/mutant.hpp
Executable file
83
include/boost/bimap/relation/detail/mutant.hpp
Executable 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
|
||||
|
||||
105
include/boost/bimap/relation/detail/static_access_builder.hpp
Executable file
105
include/boost/bimap/relation/detail/static_access_builder.hpp
Executable 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
Reference in New Issue
Block a user