File: dynamic_property_map.html

package info (click to toggle)
boost 1.33.1-10
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 100,948 kB
  • ctags: 145,103
  • sloc: cpp: 573,492; xml: 49,055; python: 15,626; ansic: 13,588; sh: 2,099; yacc: 858; makefile: 660; perl: 427; lex: 111; csh: 6
file content (364 lines) | stat: -rw-r--r-- 19,748 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.3: http://docutils.sourceforge.net/" />
<title>Boost Dynamic Property Maps</title>
<link rel="stylesheet" href="../../../boost.css" type="text/css" />
</head>
<body>
<h1 class="title"><a class="reference" href="../../../index.htm"><img align="middle" alt="Boost" src="../../../boost.png" /></a> Dynamic Property Maps</h1>
<div class="document" id="logo-dynamic-property-maps">
<div class="section" id="summary">
<h1><a class="toc-backref" href="#id2" name="summary">Summary</a></h1>
<p>The dynamic property map interfaces provides access to a collection of
property maps through a dynamically-typed interface. An algorithm can
use it to manipulate property maps without knowing their key or
value types at compile-time. Type-safe codes can use dynamic property
maps to interface more easily and completely with scripting languages
and other text-based representations of key-value data.</p>
<div class="contents topic" id="contents">
<p class="topic-title first"><a name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#summary" id="id2" name="id2">Summary</a></li>
<li><a class="reference" href="#introduction" id="id3" name="id3">Introduction</a><ul>
<li><a class="reference" href="#fred-s-info-revisited" id="id4" name="id4">&quot;Fred's Info&quot; Revisited</a></li>
</ul>
</li>
<li><a class="reference" href="#reference" id="id5" name="id5">Reference</a><ul>
<li><a class="reference" href="#member-functions" id="id6" name="id6">Member Functions</a></li>
<li><a class="reference" href="#free-functions" id="id7" name="id7">Free functions</a></li>
<li><a class="reference" href="#exceptions" id="id8" name="id8">Exceptions</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id3" name="introduction">Introduction</a></h1>
<p>The Boost Property Map library specifies statically type-safe
interfaces through which key-value pairs can be manipulated by 
generic algorithms. Typically, an algorithm that uses property maps is
parameterized on the types of the property maps it uses, and it
manipulates them using the interfaces specified by the
Boost Property Map Library.</p>
<p>The following generic function illustrates property map basics.</p>
<pre class="literal-block">
template &lt;typename AgeMap, typename GPAMap&gt;
void 
manipulate_freds_info(AgeMap ages, GPAMap gpas) {

  typedef typename boost::property_traits&lt;AgeMap&gt;::key_type name_type;
  typedef typename boost::property_traits&lt;AgeMap&gt;::value_type age_type;
  typedef typename boost::property_traits&lt;GPAMap&gt;::value_type gpa_type;

  name_type fred = &quot;Fred&quot;;

  age_type old_age = get(ages, fred);
  gpa_type old_gpa = get(gpas, fred);

  std::cout &lt;&lt; &quot;Fred's old age: &quot; &lt;&lt; old_age &lt;&lt; &quot;\n&quot;
            &lt;&lt; &quot;Fred's old gpa: &quot; &lt;&lt; old_gpa &lt;&lt; &quot;\n&quot;;

  age_type new_age = 18;
  gpa_type new_gpa = 3.9;
  put(ages, fred, new_age);
  put(gpas, fred, new_gpa);
}
</pre>
<p>The function is parameterized on two property map types, <tt class="literal"><span class="pre">AgeMap</span></tt> and
<tt class="literal"><span class="pre">GPAMap</span></tt>, and takes a value parameter for each of those types.  The
function uses the <tt class="literal"><span class="pre">property_traits</span></tt> interface to ascertain, at
compile-time, the value and key types of the property maps.  The code
then retrieves Fred's old information, using the <tt class="literal"><span class="pre">get</span></tt> function, and
updates it using the <tt class="literal"><span class="pre">put</span></tt> function. The <tt class="literal"><span class="pre">get</span></tt> function is required by the
Readable Property Map concept and both <tt class="literal"><span class="pre">get</span></tt> and <tt class="literal"><span class="pre">put</span></tt> are required by the
Read/Write Property Map concept.</p>
<p>The above function not only requires the two type parameters to model
property map concepts, but also makes some extra assumptions.
<tt class="literal"><span class="pre">AgeMap</span></tt> and <tt class="literal"><span class="pre">GPAMap</span></tt> must have the same key type, and that type must be
constructable from a string.  Furthermore, <tt class="literal"><span class="pre">AgeMap</span></tt>'s value type must be
constructable from an <tt class="literal"><span class="pre">int</span></tt>.  Although these requirements are not
explicitly stated, they are statically checked during compilation and
failure to meet them yields compile-time errors.</p>
<p>Although the static typing of property map interfaces usually provides
desirable compile-time safety, some algorithms require a more dynamic
interface to property maps. For example, the Boost Graph Library (BGL)
provides functions that can initialize a graph by interpreting the
contents of a textual graph description (i.e. a GraphML file).  Such
general-purpose graph description languages can specify an arbitrary
number of edge and vertex properties, using strings to represent the
key-value pairs.  A graph reader function should capture these
arbitrary properties, but since function templates can only be
parameterized on a fixed number of property maps, the traditional
techniques for handling property maps do not suffice to implement them.</p>
<p>Dynamic property maps specifically address the need for an interface
to property maps whose checking is delayed to runtime.  Several
components combine to provide support for dynamic property maps. The
<tt class="literal"><span class="pre">dynamic_properties</span></tt> class collects a
group of heterogenous objects that model concepts from
the Boost Property Map library. Each property map is assigned a
string-based key when it is added to the collection, and it can be
addressed using that key.  Internally, <tt class="literal"><span class="pre">dynamic_properties</span></tt> adapts
each contained property map with the dynamic property map interface,
which provides <tt class="literal"><span class="pre">get</span></tt> and <tt class="literal"><span class="pre">put</span></tt> functions that
can be called using values of any type that meets a few requirements.
Internally, the dynamic property map converts key and value pairs to
meet the requirements of the underlying property map or signals a
runtime exception if it cannot.</p>
<div class="section" id="fred-s-info-revisited">
<h2><a class="toc-backref" href="#id4" name="fred-s-info-revisited">&quot;Fred's Info&quot; Revisited</a></h2>
<p>Here's what the example above looks like using the
<tt class="literal"><span class="pre">dynamic_properties</span></tt> interface:</p>
<pre class="literal-block">
void manipulate_freds_info(boost::dynamic_properties&amp; properties)
{
  using boost::get;
  std::string fred = &quot;Fred&quot;;

  int old_age = get&lt;int&gt;(&quot;age&quot;, properties, fred);
  std::string old_gpa = get(&quot;gpa&quot;, properties, fred);

  std::cout &lt;&lt; &quot;Fred's old age: &quot; &lt;&lt; old_age &lt;&lt; &quot;\n&quot;
            &lt;&lt; &quot;Fred's old gpa: &quot; &lt;&lt; old_gpa &lt;&lt; &quot;\n&quot;;

  std::string new_age = &quot;18&quot;;
  double new_gpa = 3.9;
  put(&quot;age&quot;,properties,fred,new_age);
  put(&quot;gpa&quot;,properties,fred,new_gpa);
}
</pre>
<p>The new function is not a template parameterized on the property map
types but instead a concrete function that takes a <tt class="literal"><span class="pre">dynamic_properties</span></tt>
object.  Furthermore, the code no longer makes reference to key or
value types: keys and values are represented with strings.
Nonetheless the function still uses non-string types where they are
useful.  For instance, Fred's old age is represented using an <tt class="literal"><span class="pre">int</span></tt>.
It's value is retreived by calling <tt class="literal"><span class="pre">get</span></tt> with a
type parameter, which determines its return type.  Finally, the
<tt class="literal"><span class="pre">get</span></tt> and <tt class="literal"><span class="pre">put</span></tt> functions are each supplied a string-based key that
differs depending on the property of concern.</p>
<p>Here's an example of how the above function might be called.</p>
<pre class="literal-block">
int main()
{
  using boost::get;

  // build property maps using associative_property_map
  std::map&lt;std::string, int&gt; name2age;
  std::map&lt;std::string, double&gt; name2gpa;
  boost::associative_property_map&lt; std::map&lt;std::string, int&gt; &gt;
    age_map(name2age);
  boost::associative_property_map&lt; std::map&lt;std::string, double&gt; &gt;
    gpa_map(name2gpa);

  std::string fred(&quot;Fred&quot;);
  // add key-value information
  name2age.insert(make_pair(fred,17));
  name2gpa.insert(make_pair(fred,2.7));

  // build and populate dynamic interface
  boost::dynamic_properties properties;
  properties.property(&quot;age&quot;,age_map);
  properties.property(&quot;gpa&quot;,gpa_map);

  manipulate_freds_info(properties);

  std::cout &lt;&lt; &quot;Fred's age: &quot; &lt;&lt; get(age_map,fred) &lt;&lt; &quot;\n&quot;
            &lt;&lt; &quot;Fred's gpa: &quot; &lt;&lt; get(gpa_map,fred) &lt;&lt; &quot;\n&quot;;       
}
</pre>
<p>The code first creates two property maps using <tt class="literal"><span class="pre">std::map</span></tt> and the
<tt class="literal"><span class="pre">associative_property_map</span></tt> adaptor.  After initializing the
property maps with key-value data, it constructs a
<tt class="literal"><span class="pre">dynamic_properties</span></tt> object and adds to it both property maps,
keyed on the strings &quot;age&quot; and &quot;gpa&quot;.  Finally <tt class="literal"><span class="pre">manipulate_freds_info</span></tt>
is passed the <tt class="literal"><span class="pre">dynamic_properties</span></tt> object and the results of its changes are
displayed.</p>
<p>As shown above, the <tt class="literal"><span class="pre">dynamic_properties</span></tt> object provides, where needed, a
dynamically-typed interface to property maps yet preserves the static
typing of property map uses elsewhere in an application.</p>
</div>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id5" name="reference">Reference</a></h1>
<pre class="literal-block">
class dynamic_properties
</pre>
<p>The <tt class="literal"><span class="pre">dynamic_properties</span></tt> class provides a dynamically-typed interface to
a set of property maps. To use it, one must populate
an object of this class with property maps using the <tt class="literal"><span class="pre">property</span></tt> member
function.</p>
<div class="section" id="member-functions">
<h2><a class="toc-backref" href="#id6" name="member-functions">Member Functions</a></h2>
<pre class="literal-block">
dynamic_properties()
dynamic_properties(
  const boost::function&lt;
    std::auto_ptr&lt;dynamic_property_map&gt; (
      const std::string&amp;, const boost::any&amp;, const boost::any&amp;)
    &gt;&amp; fn)
</pre>
<p>A <tt class="literal"><span class="pre">dynamic_properties</span></tt> object can be constructed with a function object
that, when called, creates a new property map.  If an attempt is made
to <tt class="literal"><span class="pre">put</span></tt> a key-value pair to a nonexistent <tt class="literal"><span class="pre">dynamic_properties</span></tt> key,
then this function is called with the <tt class="literal"><span class="pre">dynamic_properties</span></tt> key and the
intended property key and value .  If <tt class="literal"><span class="pre">dynamic_properties</span></tt> is
default-constructed, such a <tt class="literal"><span class="pre">put</span></tt> attempt throws 
<tt class="literal"><span class="pre">property_not_found</span></tt>.</p>
<pre class="literal-block">
template&lt;typename PropertyMap&gt;
dynamic_properties&amp; 
property(const std::string&amp; name, PropertyMap property_map)
</pre>
<p>This member function adds a property map to the set of maps contained,
using <tt class="literal"><span class="pre">name</span></tt> as its key.</p>
<p>Requirements: <tt class="literal"><span class="pre">PropertyMap</span></tt> must model Readable Property Map or
Read/Write Property Map.</p>
<pre class="literal-block">
void insert(const std::string&amp; name, std::auto_ptr&lt;dynamic_property_map&gt; pm)
</pre>
<p>This member function directly adds a <tt class="literal"><span class="pre">dynamic_property_map</span></tt>
to the collection, using <tt class="literal"><span class="pre">name</span></tt> as its key.</p>
<pre class="literal-block">
iterator begin()
const_iterator begin() const
</pre>
<p>This member function returns an iterator over the set of property maps
held by the <tt class="literal"><span class="pre">dynamic_properties</span></tt> object.</p>
<pre class="literal-block">
iterator end()
const_iterator end() const
</pre>
<p>This member function returns a terminal iterator over the set of
dynamic property maps held by the <tt class="literal"><span class="pre">dynamic_properties</span></tt> object.  It is used to
terminate traversals over the set of dynamic property maps</p>
<pre class="literal-block">
iterator lower_bound(const std::string&amp; name) 
</pre>
<p>This member function returns an iterator that points to the first
property map whose <tt class="literal"><span class="pre">dynamic_properties</span></tt> key is <tt class="literal"><span class="pre">name</span></tt>.  
Bear in mind that multiple property maps may have the same
<tt class="literal"><span class="pre">dynamic_properties</span></tt> key, so long as their property map key types differ.</p>
<p>Invariant: The range [ lower_bound(name), end() ) contains every
property map that has name for its <tt class="literal"><span class="pre">dynamic_properties</span></tt> key.</p>
</div>
<div class="section" id="free-functions">
<h2><a class="toc-backref" href="#id7" name="free-functions">Free functions</a></h2>
<pre class="literal-block">
template&lt;typename Key, typename Value&gt;
bool put(const std::string&amp; name, dynamic_properties&amp; dp, const Key&amp; key, 
         const Value&amp; value)
</pre>
<p>This function adds a key-value pair to the property map with the matching name
and key type. If no matching property map is found and a generator function was
supplied at construction, then that function is used to create a new
property map; if the <tt class="literal"><span class="pre">dynamic_properties</span></tt> object was
default-constructed, then <tt class="literal"><span class="pre">property_not_found</span></tt> is
thrown. Furthermore, if the property map found does not support put,
<tt class="literal"><span class="pre">dynamic_const_put_error</span></tt> is thrown.</p>
<pre class="literal-block">
template&lt;typename Value, typename Key&gt;
Value get(const std::string&amp; name, const dynamic_properties&amp; dp, 
          const Key&amp; key)
</pre>
<p>This function gets the value from the property-map whose namee is
given and whose key type matches. If <tt class="literal"><span class="pre">Value</span></tt> is <tt class="literal"><span class="pre">std::string</span></tt>, then the
property map's value type must either be <tt class="literal"><span class="pre">std::string</span></tt> or model
OutputStreamable.  In the latter case, the <tt class="literal"><span class="pre">get</span></tt> function converts the
value to a string.  If no matching property map is found,
<tt class="literal"><span class="pre">dynamic_get_failure</span></tt> is thrown.</p>
<hr />
<pre class="literal-block">
class dynamic_property_map
</pre>
<p>This class describes the interface used by <tt class="literal"><span class="pre">dynamic_properties</span></tt> to
interact with a user's property maps polymorphically.</p>
<pre class="literal-block">
boost::any get(const any&amp; key)
</pre>
<p>Given a representation of a key, return the value associated with that key.</p>
<p>Requirement:
1) The object passed as the key must be convertible to a value of the
map's key type. Details of that conversion are unspecified.
2) For this expression to be valid, the key must be
associated with some value, otherwise the result is undefined.</p>
<pre class="literal-block">
std::string get_string(const any&amp; key) 
</pre>
<p>Given a representation of a key, return the string representation
of the value associated with that key.</p>
<p>Requirements:
1) The object passed as the key must be convertible to the
property map's key type. Details of that conversion are unspecified.
2) For this expression to be valid, the key must be
associated with some value, otherwise the result is undefined.
3) The value type of the property map must model Output Streamable.</p>
<pre class="literal-block">
void put(const any&amp; key, const any&amp; value) 
</pre>
<p>Given a representation of a key and a representation of a value, the
key and value are associated in the property map.</p>
<p>Requirements:
1) The object passed as the key must be convertible to the
property map's key type. Details of that conversion are unspecified.
2) The object passed as the value must be convertible to the
property map's value type. Details of that conversion are unspecified.
3) The property map need not support this member function, in which
case an error will be signaled.  This is the runtime analogue of the
Readable Property Map concept.</p>
<pre class="literal-block">
const std::type_info&amp; key() const 
</pre>
<p>Returns a <tt class="literal"><span class="pre">type_info</span></tt> object that represents the property map's key type.</p>
<pre class="literal-block">
const std::type_info&amp; value() const 
</pre>
<p>Returns a <tt class="literal"><span class="pre">type_info</span></tt> object that represents the property map's value type.</p>
</div>
<div class="section" id="exceptions">
<h2><a class="toc-backref" href="#id8" name="exceptions">Exceptions</a></h2>
<pre class="literal-block">
struct dynamic_property_exception : public std::exception {
  virtual ~dynamic_property_exception() throw() {}
};

struct property_not_found : public std::exception {
  std::string property;
  property_not_found(const std::string&amp; property);
  virtual ~property_not_found() throw();

  const char* what() const throw();
};

struct dynamic_get_failure : public std::exception {
  std::string property;
  dynamic_get_failure(const std::string&amp; property);
  virtual ~dynamic_get_failure() throw();

  const char* what() const throw();
};

struct dynamic_const_put_error  : public std::exception {
  virtual ~dynamic_const_put_error() throw();

  const char* what() const throw();
};
</pre>
<p>Under certain circumstances, calls to <tt class="literal"><span class="pre">dynamic_properties</span></tt> member
functions will throw one of the above exceptions.  The three concrete
exceptions can all be caught using the general
<tt class="literal"><span class="pre">dynamic_property_exception</span></tt> moniker when greater precision is not
needed.  In addition, all of the above exceptions derive from the
standard <tt class="literal"><span class="pre">std::exception</span></tt> for even more generalized error handling.
The specific circumstances that result in these exceptions are
described above.</p>
</div>
</div>
</div>
<hr class="footer" />
<div class="footer">
Generated on: 2005-02-08 16:39 UTC.
</div>
</body>
</html>