property_map.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <HTML>
  2. <!--
  3. Copyright (c) Jeremy Siek 2000
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <Head>
  9. <Title>Property Map Library</Title>
  10. <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
  11. ALINK="#ff0000">
  12. <IMG SRC="../../../boost.png"
  13. ALT="C++ Boost" width="277" height="86">
  14. <BR Clear>
  15. <H1><A NAME="sec:property-maps"></A>
  16. Boost Property Map Library
  17. </H1>
  18. <p>The Boost Property Map Library consists mainly of interface
  19. specifications in the form of concepts (similar to the iterator
  20. concepts in the STL <a
  21. href="http://www.sgi.com/tech/stl/stl_introduction.html">[2]</a>).
  22. These interface specifications are intended for use by implementors of
  23. generic libraries in communicating requirements on template parameters
  24. to their users. In particular, the Boost Property Map concepts define
  25. a general purpose interface for mapping key objects to corresponding
  26. value objects, thereby hiding the details of how the mapping is
  27. implemented from algorithms. The implementation of types fulfilling
  28. the property map interface is up to the client of the algorithm to
  29. provide. The property map requirements are purposefully vague on the
  30. type of the key and value objects to allow for the utmost genericity
  31. in the function templates of the generic library.
  32. </p>
  33. <p>
  34. The need for the property map interface came from the <a
  35. href="../../graph/doc/index.html">Boost Graph Library</a> (BGL), which
  36. contains many examples of algorithms that use the property map
  37. concepts to specify their interface. For an example, note the
  38. <tt>ColorMap</tt> template parameter of the <a
  39. href="../../graph/doc/breadth_first_search.html">
  40. <tt>breadth_first_search</tt></a>. In addition, the BGL contains many
  41. examples of concrete types that implement the property map interface.
  42. The <a href="../../graph/doc/adjacency_list.html">
  43. <tt>adjacency_list</tt></a> class implements property maps for
  44. accessing objects (properties) that are attached to vertices and edges
  45. of the graph.
  46. </p>
  47. <p>
  48. The Boost Property Map Library also contains a <a
  49. href="#sec:property-map-types"> few adaptors</a> that convert commonly
  50. used data-structures that implement a mapping operation, such as
  51. builtin arrays (pointers), iterators, and <a
  52. href="http://www.sgi.com/tech/stl/Map.html"> <tt>std::map</tt></a>, to
  53. have the property map interface. These adaptors are not meant to
  54. fulfill all mapping needs, but are to serve as an example of how to
  55. implement the interface as well as covering a few common cases. See
  56. the header files for details.
  57. </p>
  58. <p>Property maps are statically-typed entities. If you need to access
  59. property maps in a more dynamic setting (e.g., because you're reading
  60. an unknown set of attributes from a file), you can use the <a
  61. href="dynamic_property_map.html"><code>dynamic_properties</code></a>
  62. class to access a set of property maps through a dynamically-typed
  63. interface. </p>
  64. <h2><A NAME="sec:property-map-concepts"></A>
  65. Property Map Concepts
  66. </h2>
  67. The property map interface consists of a set of concepts (see
  68. definition of &quot;concept&quot; in <a
  69. href="../../concept_check/concept_check.htm#introduction">[1]</a> and <a
  70. href="http://www.sgi.com/tech/stl/stl_introduction.html">[2]</a>) that
  71. define a syntax for mapping key objects to corresponding value
  72. objects. Since the property map operations are global functions
  73. (actually they don't have to be global, but they are always called
  74. unqualified and may be found via argument dependent lookup), it is
  75. possible to overload the map functions such that nearly arbitrary
  76. property map types and key types can be used. The interface for
  77. property maps consists of three functions: <tt>get()</tt>,
  78. <tt>put()</tt>, and <tt>operator[]</tt>. The following concrete
  79. example from <a href="../example/example1.cpp">example1.cpp</a> shows how the
  80. three functions could be used to access the addresses associated with
  81. various people. We use a separate function template here to highlight
  82. the parts of the program that use the property map concept
  83. interface. In the <tt>main()</tt> function we use <tt>std::map</tt>
  84. and <tt>boost::associative_property_map</tt>, but it would have been
  85. OK to use any type (including a custom type that you create) that
  86. fulfills the property map requirements.
  87. <pre>#include &lt;iostream&gt;
  88. #include &lt;map&gt;
  89. #include &lt;string&gt;
  90. #include &lt;boost/property_map/property_map.hpp&gt;
  91. template &lt;typename AddressMap&gt;
  92. void foo(AddressMap address)
  93. {
  94. typedef typename boost::property_traits&lt;AddressMap&gt;::value_type value_type;
  95. typedef typename boost::property_traits&lt;AddressMap&gt;::key_type key_type;
  96. value_type old_address, new_address;
  97. key_type fred = &quot;Fred&quot;;
  98. old_address = get(address, fred);
  99. new_address = &quot;384 Fitzpatrick Street&quot;;
  100. put(address, fred, new_address);
  101. key_type joe = &quot;Joe&quot;;
  102. value_type&amp; joes_address = address[joe];
  103. joes_address = &quot;325 Cushing Avenue&quot;;
  104. }
  105. int
  106. main()
  107. {
  108. std::map&lt;std::string, std::string&gt; name2address;
  109. boost::associative_property_map&lt; std::map&lt;std::string, std::string&gt; &gt;
  110. address_map(name2address);
  111. name2address.insert(make_pair(std::string(&quot;Fred&quot;),
  112. std::string(&quot;710 West 13th Street&quot;)));
  113. name2address.insert(make_pair(std::string(&quot;Joe&quot;),
  114. std::string(&quot;710 West 13th Street&quot;)));
  115. foo(address_map);
  116. for (std::map&lt;std::string, std::string&gt;::iterator i = name2address.begin();
  117. i != name2address.end(); ++i)
  118. std::cout &lt;&lt; i-&gt;first &lt;&lt; &quot;: &quot; &lt;&lt; i-&gt;second &lt;&lt; &quot;\n&quot;;
  119. return EXIT_SUCCESS;
  120. }</pre>
  121. <p>
  122. For each property map object there is a set of <i>valid keys</i>
  123. for which the mapping to value objects is defined. Invoking a
  124. property map function on an <i>invalid</i> key results in
  125. undefined behavior. The property map concepts do not specify how
  126. this set of valid keys is created or modified. A function that uses a
  127. property map must specify the expected set of valid keys in its
  128. preconditions.
  129. <p>
  130. The need for property maps came out of the design of the Boost
  131. Graph Library, whose algorithms needed an interface for accessing
  132. properties attached to vertices and edges in a graph. In this context
  133. the vertex and edge descriptors are the key type of the property
  134. maps.
  135. <!-- historical note about Decorators and Data Maps -->
  136. <P>
  137. Several categories of property maps provide
  138. different access capabilities:
  139. <DL>
  140. <DT><STRONG>readable</STRONG></DT>
  141. <DD>The associated property data can only be read.
  142. The data is returned by-value. Many property maps defining the
  143. problem input (such as edge weight) can be defined as readable
  144. property maps.
  145. <P>
  146. </DD>
  147. <DT><STRONG>writeable</STRONG></DT>
  148. <DD>The associated property can only be written to.
  149. The parent array used to record the paths in a bread-first search tree
  150. is an example of a property map that would be defined writeable.
  151. <P>
  152. </DD>
  153. <DT><STRONG>read/write</STRONG></DT>
  154. <DD>The associated property can both be written and read.
  155. The distance property use in Dijkstra's shortest paths algorithm
  156. would need to provide both read and write capabilities.
  157. <P>
  158. </DD>
  159. <DT><STRONG>lvalue</STRONG></DT>
  160. <DD>The associated property is actually represented in
  161. memory and it is possible to get a reference to it.
  162. The property maps in the lvalue
  163. category also support the requirements for read/write property
  164. maps.
  165. <P>
  166. </DD>
  167. </DL>
  168. <P>
  169. There is a separate concept defined for each of the four property
  170. map categories. These property map concepts are listed
  171. below, with links to the documentation for each of them.
  172. <ul>
  173. <li><a href="./ReadablePropertyMap.html">ReadablePropertyMap</a></li>
  174. <li><a href="./WritablePropertyMap.html">WritablePropertyMap</a></li>
  175. <li><a href="./ReadWritePropertyMap.html">ReadWritePropertyMap</a></li>
  176. <li><a href="./LvaluePropertyMap.html">LvaluePropertyMap</a></li>
  177. </ul>
  178. <h2><a name="sec:property-map-tags">Property Map Category Tags</a></h2>
  179. <P>
  180. There is a tag struct for each of the categories of property
  181. maps, which is defined in the header
  182. <tt>&lt;boost/property_map/property_map.hpp&gt;</tt>.
  183. <PRE>namespace boost {
  184. struct readable_property_map_tag { };
  185. struct writable_property_map_tag { };
  186. struct read_write_property_map_tag :
  187. public readable_property_map_tag,
  188. public writable_property_map_tag { };
  189. struct lvalue_property_map_tag :
  190. public read_write_property_map_tag { };
  191. }</PRE>
  192. <h2><a name="sec:property-map-traits">Property Map Traits</a></h2>
  193. <P>
  194. Similar to the <TT>std::iterator_traits</TT> class of the STL, there
  195. is a <TT>boost::property_traits</TT> class that can be used to deduce
  196. the types associated with a property map type: the key and value
  197. types, and the property map category. There is a specialization
  198. of <TT>boost::property_traits</TT> so that pointers can be used as
  199. property map objects. In addition, the property map
  200. functions are overloaded for pointers. These traits classes and
  201. functions are defined in <tt>&lt;boost/property_map/property_map.hpp&gt;</tt>.
  202. <PRE>namespace boost {
  203. template &lt;typename PropertyMap&gt;
  204. struct property_traits {
  205. typedef typename PropertyMap::key_type key_type;
  206. typedef typename PropertyMap::value_type value_type;
  207. typedef typename PropertyMap::reference reference;
  208. typedef typename PropertyMap::category category;
  209. };
  210. }</PRE>
  211. <h2><a name="sec:property-map-types">Property Map Types</a></h2>
  212. <ul>
  213. <li>Builtin C++ pointer types.<br>
  214. The following specialization of the <tt>property_traits</tt> class
  215. and the overloads of <tt>put()</tt> and <tt>get()</tt> make it
  216. possible to use builtin C++ pointer types as property maps. These
  217. are defined in <tt>boost/property_map/property_map.hpp</tt>. More specifically,
  218. it means that <tt>T*</tt> is a model of <a
  219. href="./LvaluePropertyMap.html">LvaluePropertyMap</a>, given a key
  220. type that is at least convertible <tt>std::ptrdiff_t</tt>.
  221. <PRE>namespace boost {
  222. // specialization for using pointers as property maps
  223. template &lt;typename T&gt;
  224. struct property_traits&lt;T*&gt; {
  225. typedef T value_type;
  226. typedef T&amp; reference;
  227. typedef std::ptrdiff_t key_type;
  228. typedef random_access_iterator_pa_tag category;
  229. };
  230. // overloads of the property map functions for pointers
  231. template&lt;&gt;
  232. void put(T* pmap, std::ptrdiff_t k, const T&amp; val) { pmap[k] = val; }
  233. template&lt;&gt;
  234. const T&amp; get(const T* pmap, std::ptrdiff_t k) { return pmap[k]; }
  235. }</PRE>
  236. </li>
  237. <li><a href="./identity_property_map.html">identity_property_map and typed_identity_property_map</a> </li>
  238. <li><a href="./function_property_map.html">function_property_map</a> </li>
  239. <li><a href="./iterator_property_map.html">iterator_property_map</a></li>
  240. <li><a href="./shared_array_property_map.html">shared_array_property_map</a></li>
  241. <li><a href="./associative_property_map.html">associative_property_map</a></li>
  242. <li><a href="./const_assoc_property_map.html">const_associative_property_map</a></li>
  243. <li><a href="./vector_property_map.html">vector_property_map</a></li>
  244. <li><a href="./ref_property_map.html">ref_property_map</a> </li>
  245. <li><a href="./static_property_map.html">static_property_map</a> </li>
  246. <li><a href="./transform_value_property_map.html">transform_value_property_map</a> </li>
  247. <li><a href="./compose_property_map.html">compose_property_map</a> </li>
  248. </ul>
  249. <h3>History</h3>
  250. The property map interface originated as <i>data accessors</i> in
  251. Dietmar K&uuml;hl's Masters Thesis on generic graph algorithms. The
  252. property map idea also appeared under the guise of <i>decorators</i>
  253. in early versions of the Generic Graph Component Library (GGCL), which
  254. is now the Boost Graph Library (BGL). The main motivation for the
  255. property map interface was to support the access of data associated
  256. with vertices and edges in a graph, though the applicability of
  257. property maps goes beyond this.
  258. <h3>Acknowledgments</h3>
  259. Thanks go to Dietmar K&uuml;hl for coming up with this mechanism, and
  260. thanks go to the Boost members who helped refine and improve the
  261. property map interface. Thanks to Dave Abrahams for managing the
  262. formal review of the BGL which included the property map library.
  263. <h3>Notes to Implementors</h3>
  264. Copying a property map should be inexpensive since they are often
  265. passed by value.
  266. <br>
  267. <HR>
  268. <TABLE>
  269. <TR valign=top>
  270. <TD nowrap>Copyright &copy; 2000-2002</TD><TD>
  271. <a HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>, Indiana University (<A HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)
  272. </TD></TR></TABLE>
  273. </BODY>
  274. </HTML>
  275. <!-- LocalWords: ALT STL html genericity BGL ColorMap htm cpp iostream hpp hl
  276. -->
  277. <!-- LocalWords: typename AddressMap foo fred joe joes int writeable lvalue
  278. -->
  279. <!-- LocalWords: ReadablePropertyMap WritablePropertyMap ReadWritePropertyMap
  280. -->
  281. <!-- LocalWords: LvaluePropertyMap struct namespace PropertyMap pmap const
  282. -->
  283. <!-- LocalWords: val Dietmar hl's GGCL Abrahams
  284. -->