blob: a4b18ae99a4b8c995557d5ff580495c40a6f55fc [file] [log] [blame]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Additional information</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Boost.Bimap">
<link rel="up" href="../the_tutorial.html" title="The tutorial">
<link rel="prev" href="unconstrained_sets.html" title="Unconstrained Sets">
<link rel="next" href="complete_instantiation_scheme.html" title="Complete instantiation scheme">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="unconstrained_sets.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../the_tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="complete_instantiation_scheme.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_bimap.the_tutorial.additional_information"></a><a class="link" href="additional_information.html" title="Additional information">Additional
information</a>
</h3></div></div></div>
<p>
Bidirectional maps may have associated information about each relation. Suppose
we want to represent a books and author bidirectional map.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">bimap</span><span class="special">&lt;</span>
<span class="identifier">multiset_of</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;,</span> <span class="comment">// author
</span> <span class="identifier">set_of</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="comment">// title
</span>
<span class="special">&gt;</span> <span class="identifier">bm_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">bm_type</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">book</span><span class="special">;</span>
<span class="identifier">bm_type</span> <span class="identifier">bm</span><span class="special">;</span>
<span class="identifier">bm</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span> <span class="identifier">book</span><span class="special">(</span> <span class="string">"Bjarne Stroustrup"</span> <span class="special">,</span> <span class="string">"The C++ Programming Language"</span> <span class="special">)</span> <span class="special">);</span>
<span class="identifier">bm</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span> <span class="identifier">book</span><span class="special">(</span> <span class="string">"Scott Meyers"</span> <span class="special">,</span> <span class="string">"Effective C++"</span> <span class="special">)</span> <span class="special">);</span>
<span class="identifier">bm</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span> <span class="identifier">book</span><span class="special">(</span> <span class="string">"Andrei Alexandrescu"</span> <span class="special">,</span> <span class="string">"Modern C++ Design"</span> <span class="special">)</span> <span class="special">);</span>
<span class="comment">// Print the author of Modern C++
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">right</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span> <span class="string">"Modern C++ Design"</span> <span class="special">);</span>
</pre>
<p>
</p>
<p>
Suppose now that we want to store abstract of each book. We have two options:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
Books name are unique identifiers, so we can create a separate <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span> <span class="identifier">string</span><span class="special">,</span> <span class="identifier">string</span> <span class="special">&gt;</span></code>
that relates books names with abstracts.
</li>
<li class="listitem">
We can use <a href="http://www.boost.org/libs/multi_index/doc/index.html" target="_top"><span class="bold"><strong>Boost.MultiIndex</strong></span></a> for the new beast.
</li>
</ol></div>
<p>
Option 1 is the wrong approach, if we go this path we lost what bimap has
won us. We now have to maintain the logic of two interdependent containers,
there is an extra string stored for each book name, and the performance will
be worse. This is far away from being a good solution.
</p>
<p>
Option 2 is correct. We start thinking books as entries in a table. So it
makes sense to start using Boost.MultiIndex. We can then add the year of
publication, the price, etc... and we can index this new items too. So Boost.MultiIndex
is a sound solution for our problem.
</p>
<p>
The thing is that there are cases where we want to maintain bimap semantics
(use <code class="computeroutput"><span class="identifier">at</span><span class="special">()</span></code>
to find an author given a book name and the other way around) and add information
about the relations that we are sure we will not want to index later (like
the abstracts). Option 1 is not possible, option 2 neither.
</p>
<p>
Boost.Bimap provides support for this kind of situations by means of an embedded
information member. You can pass an extra parameter to a bimap: <code class="computeroutput"><span class="identifier">with_info</span><span class="special">&lt;</span>
<span class="identifier">InfoType</span> <span class="special">&gt;</span></code>
and an <code class="computeroutput"><span class="identifier">info</span></code> member of type
<code class="computeroutput"><span class="identifier">InfoType</span></code> will appear in the
relation and bimap pairs.
</p>
<p>
<span class="inlinemediaobject"><img src="../../images/bimap/relation.and.pair.with.info.png" alt="relation.and.pair.with.info"></span>
</p>
<p>
Relations and bimap pairs constructors will take an extra argument. If only
two arguments are used, the information will be initialized with their default
constructor.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">bimap</span><span class="special">&lt;</span>
<span class="identifier">multiset_of</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;,</span> <span class="comment">// author
</span> <span class="identifier">set_of</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;,</span> <span class="comment">// title
</span>
<span class="identifier">with_info</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="comment">// abstract
</span>
<span class="special">&gt;</span> <span class="identifier">bm_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">bm_type</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">book</span><span class="special">;</span>
<span class="identifier">bm_type</span> <span class="identifier">bm</span><span class="special">;</span>
<span class="identifier">bm</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span>
<span class="identifier">book</span><span class="special">(</span> <span class="string">"Bjarne Stroustrup"</span> <span class="special">,</span> <span class="string">"The C++ Programming Language"</span><span class="special">,</span>
<span class="string">"For C++ old-timers, the first edition of this book is"</span>
<span class="string">"the one that started it all&#8212;the font of our knowledge."</span> <span class="special">)</span>
<span class="special">);</span>
<span class="comment">// Print the author of the bible
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">right</span><span class="special">.</span><span class="identifier">at</span><span class="special">(</span><span class="string">"The C++ Programming Language"</span><span class="special">);</span>
<span class="comment">// Print the abstract of this book
</span><span class="identifier">bm_type</span><span class="special">::</span><span class="identifier">left_iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">left</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="string">"Bjarne Stroustrup"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">info</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
Contrary to the two key types, the information will be mutable using iterators.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">info</span> <span class="special">+=</span> <span class="string">"More details about this book"</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
A new function is included in <span class="emphasis"><em>unique</em></span> map views: <code class="computeroutput"><span class="identifier">info_at</span><span class="special">(</span><span class="identifier">key</span><span class="special">)</span></code>, that
mimics the standard <code class="computeroutput"><span class="identifier">at</span><span class="special">(</span><span class="identifier">key</span><span class="special">)</span></code> function
but returned the associated information instead of the data.
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Print the new abstract
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">right</span><span class="special">.</span><span class="identifier">info_at</span><span class="special">(</span><span class="string">"The C++ Programming Language"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
The info member can be tagged just as the left or the right member. The following
is a rewrite of the above example using user defined names:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">bimap</span><span class="special">&lt;</span>
<span class="identifier">multiset_of</span><span class="special">&lt;</span> <span class="identifier">tagged</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">author</span> <span class="special">&gt;</span> <span class="special">&gt;,</span>
<span class="identifier">set_of</span><span class="special">&lt;</span> <span class="identifier">tagged</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">title</span> <span class="special">&gt;</span> <span class="special">&gt;,</span>
<span class="identifier">with_info</span><span class="special">&lt;</span> <span class="identifier">tagged</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">abstract</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">bm_type</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">bm_type</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">book</span><span class="special">;</span>
<span class="identifier">bm_type</span> <span class="identifier">bm</span><span class="special">;</span>
<span class="identifier">bm</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span>
<span class="identifier">book</span><span class="special">(</span> <span class="string">"Bjarne Stroustrup"</span> <span class="special">,</span> <span class="string">"The C++ Programming Language"</span><span class="special">,</span>
<span class="string">"For C++ old-timers, the first edition of this book is"</span>
<span class="string">"the one that started it all&#8212;the font of our knowledge."</span> <span class="special">)</span>
<span class="special">);</span>
<span class="comment">// Print the author of the bible
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">by</span><span class="special">&lt;</span><span class="identifier">title</span><span class="special">&gt;().</span><span class="identifier">at</span><span class="special">(</span><span class="string">"The C++ Programming Language"</span><span class="special">);</span>
<span class="comment">// Print the abstract of this book
</span><span class="identifier">bm_type</span><span class="special">::</span><span class="identifier">map_by</span><span class="special">&lt;</span><span class="identifier">author</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">by</span><span class="special">&lt;</span><span class="identifier">author</span><span class="special">&gt;().</span><span class="identifier">find</span><span class="special">(</span><span class="string">"Bjarne Stroustrup"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">abstract</span><span class="special">&gt;();</span>
<span class="comment">// Contrary to the two key types, the information will be mutable
</span><span class="comment">// using iterators.
</span>
<span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">abstract</span><span class="special">&gt;()</span> <span class="special">+=</span> <span class="string">"More details about this book"</span><span class="special">;</span>
<span class="comment">// Print the new abstract
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">bm</span><span class="special">.</span><span class="identifier">by</span><span class="special">&lt;</span><span class="identifier">title</span><span class="special">&gt;().</span><span class="identifier">info_at</span><span class="special">(</span><span class="string">"The C++ Programming Language"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
<a href="../../../../example/tutorial_info_hook.cpp" target="_top">Go to source code</a>
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2006 -2007 Matias Capeletto<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="unconstrained_sets.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../the_tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="complete_instantiation_scheme.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>