]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/property_map/doc/dynamic_property_map.rst
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / property_map / doc / dynamic_property_map.rst
1 ================================
2 |(logo)|__ Dynamic Property Maps
3 ================================
4
5 .. Copyright 2004-5 The Trustees of Indiana University.
6
7 Use, modification and distribution is subject to the Boost Software
8 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 http://www.boost.org/LICENSE_1_0.txt)
10
11 .. |(logo)| image:: ../../../boost.png
12 :align: middle
13 :alt: Boost
14
15 __ ../../../index.htm
16
17 Summary
18 -------
19 The dynamic property map interfaces provides access to a collection of
20 property maps through a dynamically-typed interface. An algorithm can
21 use it to manipulate property maps without knowing their key or
22 value types at compile-time. Type-safe codes can use dynamic property
23 maps to interface more easily and completely with scripting languages
24 and other text-based representations of key-value data.
25
26 .. contents::
27
28 Introduction
29 ------------
30 The Boost Property Map library specifies statically type-safe
31 interfaces through which key-value pairs can be manipulated by
32 generic algorithms. Typically, an algorithm that uses property maps is
33 parameterized on the types of the property maps it uses, and it
34 manipulates them using the interfaces specified by the
35 Boost Property Map Library.
36
37 The following generic function illustrates property map basics.
38
39
40 ::
41
42 template <typename AgeMap, typename GPAMap>
43 void
44 manipulate_freds_info(AgeMap ages, GPAMap gpas) {
45
46 typedef typename boost::property_traits<AgeMap>::key_type name_type;
47 typedef typename boost::property_traits<AgeMap>::value_type age_type;
48 typedef typename boost::property_traits<GPAMap>::value_type gpa_type;
49
50 name_type fred = "Fred";
51
52 age_type old_age = get(ages, fred);
53 gpa_type old_gpa = get(gpas, fred);
54
55 std::cout << "Fred's old age: " << old_age << "\n"
56 << "Fred's old gpa: " << old_gpa << "\n";
57
58 age_type new_age = 18;
59 gpa_type new_gpa = 3.9;
60 put(ages, fred, new_age);
61 put(gpas, fred, new_gpa);
62 }
63
64 The function is parameterized on two property map types, ``AgeMap`` and
65 ``GPAMap``, and takes a value parameter for each of those types. The
66 function uses the ``property_traits`` interface to ascertain, at
67 compile-time, the value and key types of the property maps. The code
68 then retrieves Fred's old information, using the ``get`` function, and
69 updates it using the ``put`` function. The ``get`` function is required by the
70 Readable Property Map concept and both ``get`` and ``put`` are required by the
71 Read/Write Property Map concept.
72
73 The above function not only requires the two type parameters to model
74 property map concepts, but also makes some extra assumptions.
75 ``AgeMap`` and ``GPAMap`` must have the same key type, and that type must be
76 constructable from a string. Furthermore, ``AgeMap``'s value type must be
77 constructable from an ``int``. Although these requirements are not
78 explicitly stated, they are statically checked during compilation and
79 failure to meet them yields compile-time errors.
80
81 Although the static typing of property map interfaces usually provides
82 desirable compile-time safety, some algorithms require a more dynamic
83 interface to property maps. For example, the Boost Graph Library (BGL)
84 provides functions that can initialize a graph by interpreting the
85 contents of a textual graph description (i.e. a GraphML file). Such
86 general-purpose graph description languages can specify an arbitrary
87 number of edge and vertex properties, using strings to represent the
88 key-value pairs. A graph reader function should capture these
89 arbitrary properties, but since function templates can only be
90 parameterized on a fixed number of property maps, the traditional
91 techniques for handling property maps do not suffice to implement them.
92
93 Dynamic property maps specifically address the need for an interface
94 to property maps whose checking is delayed to runtime. Several
95 components combine to provide support for dynamic property maps. The
96 ``dynamic_properties`` class collects a
97 group of heterogenous objects that model concepts from
98 the Boost Property Map library. Each property map is assigned a
99 string-based key when it is added to the collection, and it can be
100 addressed using that key. Internally, ``dynamic_properties`` adapts
101 each contained property map with the dynamic property map interface,
102 which provides ``get`` and ``put`` functions that
103 can be called using values of any type that meets a few requirements.
104 Internally, the dynamic property map converts key and value pairs to
105 meet the requirements of the underlying property map or signals a
106 runtime exception if it cannot.
107
108
109 "Fred's Info" Revisited
110 ~~~~~~~~~~~~~~~~~~~~~~~
111 Here's what the example above looks like using the
112 ``dynamic_properties`` interface:
113
114 ::
115
116 void manipulate_freds_info(boost::dynamic_properties& properties)
117 {
118 using boost::get;
119 std::string fred = "Fred";
120
121 int old_age = get<int>("age", properties, fred);
122 std::string old_gpa = get("gpa", properties, fred);
123
124 std::cout << "Fred's old age: " << old_age << "\n"
125 << "Fred's old gpa: " << old_gpa << "\n";
126
127 std::string new_age = "18";
128 double new_gpa = 3.9;
129 put("age",properties,fred,new_age);
130 put("gpa",properties,fred,new_gpa);
131 }
132
133 The new function is not a template parameterized on the property map
134 types but instead a concrete function that takes a ``dynamic_properties``
135 object. Furthermore, the code no longer makes reference to key or
136 value types: keys and values are represented with strings.
137 Nonetheless the function still uses non-string types where they are
138 useful. For instance, Fred's old age is represented using an ``int``.
139 It's value is retreived by calling ``get`` with a
140 type parameter, which determines its return type. Finally, the
141 ``get`` and ``put`` functions are each supplied a string-based key that
142 differs depending on the property of concern.
143
144 Here's an example of how the above function might be called.
145
146 ::
147
148 int main()
149 {
150 using boost::get;
151
152 // build property maps using associative_property_map
153 std::map<std::string, int> name2age;
154 std::map<std::string, double> name2gpa;
155 boost::associative_property_map< std::map<std::string, int> >
156 age_map(name2age);
157 boost::associative_property_map< std::map<std::string, double> >
158 gpa_map(name2gpa);
159
160 std::string fred("Fred");
161 // add key-value information
162 name2age.insert(make_pair(fred,17));
163 name2gpa.insert(make_pair(fred,2.7));
164
165 // build and populate dynamic interface
166 boost::dynamic_properties properties;
167 properties.property("age",age_map);
168 properties.property("gpa",gpa_map);
169
170 manipulate_freds_info(properties);
171
172 std::cout << "Fred's age: " << get(age_map,fred) << "\n"
173 << "Fred's gpa: " << get(gpa_map,fred) << "\n";
174 }
175
176 The code first creates two property maps using ``std::map`` and the
177 ``associative_property_map`` adaptor. After initializing the
178 property maps with key-value data, it constructs a
179 ``dynamic_properties`` object and adds to it both property maps,
180 keyed on the strings "age" and "gpa". Finally ``manipulate_freds_info``
181 is passed the ``dynamic_properties`` object and the results of its changes are
182 displayed.
183
184 As shown above, the ``dynamic_properties`` object provides, where needed, a
185 dynamically-typed interface to property maps yet preserves the static
186 typing of property map uses elsewhere in an application.
187
188 Reference
189 ---------
190 ::
191
192 class dynamic_properties
193
194 The ``dynamic_properties`` class provides a dynamically-typed interface to
195 a set of property maps. To use it, one must populate
196 an object of this class with property maps using the ``property`` member
197 function.
198
199 Member Functions
200 ~~~~~~~~~~~~~~~~
201
202 ::
203
204 dynamic_properties()
205 dynamic_properties(
206 const boost::function<
207 boost::shared_ptr<dynamic_property_map> (
208 const std::string&, const boost::any&, const boost::any&)
209 >& fn)
210
211 A ``dynamic_properties`` object can be constructed with a function object
212 that, when called, creates a new property map. The library provides the
213 ``ignore_other_properties`` function object, which lets the ``dynamic_properties`` object ignore any properties that it hasn't been prepared to record.
214 If an attempt is made
215 to ``put`` a key-value pair to a nonexistent ``dynamic_properties`` key,
216 then this function is called with the ``dynamic_properties`` key and the
217 intended property key and value . If ``dynamic_properties`` is
218 default-constructed, such a ``put`` attempt throws
219 ``property_not_found``.
220
221
222 ::
223
224 template<typename PropertyMap>
225 dynamic_properties&
226 property(const std::string& name, PropertyMap property_map)
227
228 This member function adds a property map to the set of maps contained,
229 using ``name`` as its key.
230
231 Requirements: ``PropertyMap`` must model Readable Property Map or
232 Read/Write Property Map.
233
234 ::
235
236 void insert(const std::string& name, boost::shared_ptr<dynamic_property_map> pm)
237
238 This member function directly adds a ``dynamic_property_map``
239 to the collection, using ``name`` as its key.
240
241 ::
242
243 iterator begin()
244 const_iterator begin() const
245
246 This member function returns an iterator over the set of property maps
247 held by the ``dynamic_properties`` object.
248
249 ::
250
251 iterator end()
252 const_iterator end() const
253
254 This member function returns a terminal iterator over the set of
255 dynamic property maps held by the ``dynamic_properties`` object. It is used to
256 terminate traversals over the set of dynamic property maps
257
258 ::
259
260 iterator lower_bound(const std::string& name)
261
262 This member function returns an iterator that points to the first
263 property map whose ``dynamic_properties`` key is ``name``.
264 Bear in mind that multiple property maps may have the same
265 ``dynamic_properties`` key, so long as their property map key types differ.
266
267 Invariant: The range [ lower_bound(name), end() ) contains every
268 property map that has name for its ``dynamic_properties`` key.
269
270 Free functions
271 ~~~~~~~~~~~~~~
272
273 ::
274
275 boost::shared_ptr<boost::dynamic_property_map>
276 ignore_other_properties(const std::string&,
277 const boost::any&,
278 const boost::any&)
279
280 When passed to the ``dynamic_properties`` constructor, this function
281 allows the ``dynamic_properties`` object to disregard attempts to put
282 values to unknown keys without signaling an error.
283
284 ::
285
286 template<typename Key, typename Value>
287 bool put(const std::string& name, dynamic_properties& dp, const Key& key,
288 const Value& value)
289
290 This function adds a key-value pair to the property map with the
291 matching name and key type. If no matching property map is found,
292 behavior depends on the availability of a property map generator. If
293 a property map generator was supplied when the ``dynamic_properties``
294 object was constructed, then that function is used to create a new
295 property map. If the generator fails to generate a property map
296 (returns a null ``shared_ptr``), then the ``put`` function returns
297 ``false``. If, on the other hand, the ``dynamic_properties`` object
298 has no property map generator (meaning it was default-constructed),
299 then ``property_not_found`` is thrown. If a candidate property map is
300 found but it does not support ``put``, ``dynamic_const_put_error`` is
301 thrown.
302
303 ::
304
305 template<typename Value, typename Key>
306 Value get(const std::string& name, const dynamic_properties& dp,
307 const Key& key)
308
309 This function gets the value from the property-map whose namee is
310 given and whose key type matches. If ``Value`` is ``std::string``, then the
311 property map's value type must either be ``std::string`` or model
312 OutputStreamable. In the latter case, the ``get`` function converts the
313 value to a string. If no matching property map is found,
314 ``dynamic_get_failure`` is thrown.
315
316
317 =============================================================================
318
319 ::
320
321 class dynamic_property_map
322
323 This class describes the interface used by ``dynamic_properties`` to
324 interact with a user's property maps polymorphically.
325
326 ::
327
328 boost::any get(const any& key)
329
330 Given a representation of a key, return the value associated with that key.
331
332 Requirement:
333 1) The object passed as the key must be convertible to a value of the
334 map's key type. Details of that conversion are unspecified.
335 2) For this expression to be valid, the key must be
336 associated with some value, otherwise the result is undefined.
337
338 ::
339
340 std::string get_string(const any& key)
341
342 Given a representation of a key, return the string representation
343 of the value associated with that key.
344
345 Requirements:
346 1) The object passed as the key must be convertible to the
347 property map's key type. Details of that conversion are unspecified.
348 2) For this expression to be valid, the key must be
349 associated with some value, otherwise the result is undefined.
350 3) The value type of the property map must model Output Streamable.
351
352 ::
353
354 void put(const any& key, const any& value)
355
356 Given a representation of a key and a representation of a value, the
357 key and value are associated in the property map.
358
359 Requirements:
360 1) The object passed as the key must be convertible to the
361 property map's key type. Details of that conversion are unspecified.
362 2) The object passed as the value must be convertible to the
363 property map's value type. Details of that conversion are unspecified.
364 3) The property map need not support this member function, in which
365 case an error will be signaled. This is the runtime analogue of the
366 Readable Property Map concept.
367
368 ::
369
370 const std::type_info& key() const
371
372 Returns a ``type_info`` object that represents the property map's key type.
373
374 ::
375
376 const std::type_info& value() const
377
378 Returns a ``type_info`` object that represents the property map's value type.
379
380
381 Exceptions
382 ~~~~~~~~~~
383
384 ::
385
386 struct dynamic_property_exception : public std::exception {
387 virtual ~dynamic_property_exception() throw() {}
388 };
389
390 struct property_not_found : public std::exception {
391 std::string property;
392 property_not_found(const std::string& property);
393 virtual ~property_not_found() throw();
394
395 const char* what() const throw();
396 };
397
398 struct dynamic_get_failure : public std::exception {
399 std::string property;
400 dynamic_get_failure(const std::string& property);
401 virtual ~dynamic_get_failure() throw();
402
403 const char* what() const throw();
404 };
405
406 struct dynamic_const_put_error : public std::exception {
407 virtual ~dynamic_const_put_error() throw();
408
409 const char* what() const throw();
410 };
411
412
413 Under certain circumstances, calls to ``dynamic_properties`` member
414 functions will throw one of the above exceptions. The three concrete
415 exceptions can all be caught using the general
416 ``dynamic_property_exception`` moniker when greater precision is not
417 needed. In addition, all of the above exceptions derive from the
418 standard ``std::exception`` for even more generalized error handling.
419 The specific circumstances that result in these exceptions are
420 described above.