The Boost Property Map Library specifies concepts that define an
interface for mapping key objects to value objects. Algorithms can
take property maps as arguments relying on the concept definition
and be ignorant of the underlying data structures. The algorithms can
therefore be more generic. The property map concepts offer get()
and put()
functions that are used as if they are global functions; i.e,
without a namespace qualifier. Furthermore, they can offer operator[]
to access value objects.
Besides concepts, the Boost Property Map Library also contains property map types that provide property map interfaces for commonly used data structures, such as arrays, iterators, and associative maps.
Property maps are statically-typed; you can use the dynamic_properties
class
to access a set of property maps through a dynamically-typed interface (e.g.,
when you read an unknown set of attributes from a file).
The following example from shows the property map functions in use. The templated fix_squares
function has a property map as parameter.
#include <iostream> #include <boost/property_map/property_map.hpp> template <typename T> void fix_squares(T squares) // assuming that T is a property map { typedef typename boost::property_traits<T>::value_type value_type; value_type answer1 = get(squares, 1); // <- use get() to get a value value_type& answer2 = squares[2]; // <- use operator[] to get a reference //value_type& answer2 = get(squares, 2); // <- this would work too bool all_correct = true; if(answer1 != 1) { all_correct = false; put(squares, 1, 1); // <- use put() to set a value } if( answer2 != 4) { all_correct = false; answer2 = 4; // <- answer2 is a reference, hence this works // squares[2] = 4; // <- this would work too // get(squares, 2) = 4; // <- this would work too } std::cout << all_correct ? "yes, all correct" : "no, something was wrong" << std::endl; }
The following example creates a vector_property_map
, and passes it to the fix_squares
function twice:
int main() { boost::vector_property_map<int> squares; squares[1] = 2; squares[2] = 4; fix_squares(squares); // first time to verify and fix mistakes fix_squares(squares); // second time to verify that all mistakes are fixed return EXIT_SUCCESS; }
This example creates an associative_property_map
instead, and passes it to the fix_squares
function too:
#include <map> int main() { std::map<int, int> squares; boost::associative_property_map< std::map<int, int> > squares_adapted(squares); squares[1] = 1; squares[2] = 3; fix_squares(squares_adapted); // first time to verify and fix mistakes fix_squares(squares_adapted); // second time to verify that all mistakes are fixed return EXIT_SUCCESS; }
To differentiate between different forms of access, there are four property map concepts. The following table gives an overview of the property map concepts and the forms of access that they must offer:
Readable.. |
Writable.. |
ReadWrite.. |
Lvalue.. |
Mutable.. |
|
value_type v = get(pmap, key); |
X |
X |
X |
X |
|
value_type& v = get(pmap, key); |
X |
||||
value_type& v = pmap[key]; |
X |
||||
const value_type& v = get(pmap, key); |
X |
X |
|||
const value_type& v = pmap[key]; |
X |
X |
|||
put(pmap, key, value); |
X |
X |
X |
Where pmap
is a property map object, key
is a key_type
object
and value
is a value_type
object; all parameters are passed as const reference;
and the following abbreviations are used to indicate property map concepts:
Abbrevation | Full concept name | Further details |
Readable.. |
ReadablePropertyMapConcept |
readable property map concept |
Writable.. |
WriteablePropertyMapConcept |
writable property map concept |
ReadWrite.. |
ReadWritePropertyMapConcept |
read- and writable property map concept |
LValue.. |
LvaluePropertyMapConcept |
lvalue property map concepts |
Mutable.. |
Mutable_LvaluePropertyMapConcept |
lvalue property map concepts |
Each property map object has a set of valid keys for which the mapping to value objects is defined; invalid keys result in undefined behaviour. The property map concepts do not specify the set of valid keys. A function that uses a property map should specify the expected set of valid keys in its preconditions.
There is a boost::property_traits
class that can be used to deduce the types associated with a property map type. The following table gives an overview and the requirements on the trait types:
Purpose | Restrictions | |||||||||||||
|
the value type of the map |
any type |
||||||||||||
|
the key type of the map |
any type |
||||||||||||
|
the tag for the type of access by the map. See the next section for definitions of category tags. |
|
||||||||||||
boost::property_traits<PMap>::reference |
the return type of get() and operator[] |
|
Note:There is no separate property tag for Mutable_LvaluePropertyMapConcept
. And, even though lvalue_property_map_tag
is convertible to writable_property_map_tag
it does not necessarily indicate that a map of this category complies to WriteablePropertyMapConcept
.
There is a tag struct for each of the categories of property
maps, which is defined in the header <boost/property_map/property_map.hpp>
.
namespace boost { struct readable_property_map_tag { }; struct writable_property_map_tag { }; struct read_write_property_map_tag : public readable_property_map_tag, public writable_property_map_tag { }; struct lvalue_property_map_tag : public read_write_property_map_tag { }; }
The property map library provides several specific property map types that are listed in the table below. Furthermore, the header <boost/property_map/property_map.hpp>
for pointers and provides the boost::property_trait
andget()
and put()
functions for built-in C++ pointers, which means that T*
is a model of Mutable_LvaluePropertyMapConcept, with key
type std::ptrdiff_t.
Property map | Summary |
identity_property_map | returns a copy of the key as value. |
iterator_property_map | converts any random access iterator into a lvalue property map |
vector_property_map | keeps its data in a dynamically resized vector |
shared_array_property_map | keeps its data in a fixed-size boost::shared_array |
associative_property_map | wraps around a Pair Associative Container or Unique Associative Container such as std::map |
const_associative_property_map | as above but non-mutable |
ref_property_map | wraps a reference to one particular object, and returns that reference whenever a key object is input. |
Copyright © 2000-2002 | Jeremy Siek, Indiana University (jsiek@osl.iu.edu) |
Copyright © 2012 | Alex Hagen-Zanker |