#include <iostream>
#include <map>
#include <string>
#include <boost/property_map.hpp>
template <typename AddressMap>
void foo(AddressMap address)
{
typedef typename boost::property_traits<AddressMap>::value_type value_type;
typedef typename boost::property_traits<AddressMap>::key_type key_type;
value_type old_address, new_address;
key_type fred = "Fred";
old_address = get(address, fred);
new_address = "384 Fitzpatrick Street";
put(address, fred, new_address);
key_type joe = "Joe";
value_type& joes_address = address[joe];
joes_address = "325 Cushing Avenue";
}
int
main()
{
std::map<std::string, std::string> name2address;
boost::associative_property_map< std::map<std::string, std::string> >
address_map(name2address);
name2address.insert(make_pair(std::string("Fred"),
std::string("710 West 13th Street")));
name2address.insert(make_pair(std::string("Joe"),
std::string("710 West 13th Street")));
foo(address_map);
for (std::map<std::string, std::string>::iterator i = name2address.begin();
i != name2address.end(); ++i)
std::cout << i->first << ": " << i->second << "\n";
return EXIT_SUCCESS;
}
For each property map object there is a set of valid keys for which the mapping to value objects is defined. Invoking a property map function on an invalid key results in undefined behavior. The property map concepts do not specify how this set of valid keys is created or modified. A function that uses a property map must specify the expected set of valid keys in its preconditions.
The need for property maps came out of the design of the Boost Graph Library, whose algorithms needed an interface for accessing properties attached to vertices and edges in a graph. In this context the vertex and edge descriptors are the key type of the property maps.
Several categories of property maps provide different access capabilities:
There is a separate concept defined for each of the four property map categories. These property map concepts are listed below, with links to the documentation for each of them.
There is a tag struct for each of the categories of property maps, which is defined in the header <boost/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 { };
}
Similar to the std::iterator_traits class of the STL, there is a boost::property_traits class that can be used to deduce the types associated with a property map type: the key and value types, and the property map category. There is a specialization of boost::property_traits so that pointers can be used as property map objects. In addition, the property map functions are overloaded for pointers. These traits classes and functions are defined in <boost/property_map.hpp>.
namespace boost {
template <typename PropertyMap>
struct property_traits {
typedef typename PropertyMap::key_type key_type;
typedef typename PropertyMap::value_type value_type;
typedef typename PropertyMap::category category;
};
}
namespace boost {
// specialization for using pointers as property maps
template <typename T>
struct property_traits<T*> {
typedef T value_type;
typedef std::ptrdiff_t key_type;
typedef random_access_iterator_pa_tag category;
};
// overloads of the property map functions for pointers
template<>
void put(T* pmap, std::ptrdiff_t k, const T& val) { pmap[k] = val; }
template<>
const T& get(const T* pmap, std::ptrdiff_t k) { return pmap[k]; }
}
| Copyright © 2000-2002 | Jeremy Siek, Indiana University (jsiek@lsc.nd.edu) |