| 1 | <HTML> |
|---|
| 2 | <!-- |
|---|
| 3 | -- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 |
|---|
| 4 | -- |
|---|
| 5 | -- Permission to use, copy, modify, distribute and sell this software |
|---|
| 6 | -- and its documentation for any purpose is hereby granted without fee, |
|---|
| 7 | -- provided that the above copyright notice appears in all copies and |
|---|
| 8 | -- that both that copyright notice and this permission notice appear |
|---|
| 9 | -- in supporting documentation. We make no |
|---|
| 10 | -- representations about the suitability of this software for any |
|---|
| 11 | -- purpose. It is provided "as is" without express or implied warranty. |
|---|
| 12 | --> |
|---|
| 13 | <Head> |
|---|
| 14 | <Title>Concept Covering and Archetypes</Title> |
|---|
| 15 | <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" |
|---|
| 16 | ALINK="#ff0000"> |
|---|
| 17 | <IMG SRC="../../boost.png" |
|---|
| 18 | ALT="C++ Boost" width="277" height="86"> |
|---|
| 19 | |
|---|
| 20 | <BR Clear> |
|---|
| 21 | |
|---|
| 22 | <h2><a name="concept-covering">Concept Covering and Archetypes</a></h2> |
|---|
| 23 | |
|---|
| 24 | We have discussed how it is important to select the minimal |
|---|
| 25 | requirements (concepts) for the inputs to a component, but it is |
|---|
| 26 | equally important to verify that the chosen concepts <i>cover</i> the |
|---|
| 27 | algorithm. That is, any possible user error should be caught by the |
|---|
| 28 | concept checks and not let slip through. Concept coverage can be |
|---|
| 29 | verified through the use of <i>archetype classes</i>. An archetype |
|---|
| 30 | class is an exact implementation of the interface associated with a |
|---|
| 31 | particular concept. The run-time behavior of the archetype class is |
|---|
| 32 | not important, the functions can be left empty. A simple test program |
|---|
| 33 | can then be compiled with the archetype classes as the inputs to the |
|---|
| 34 | component. If the program compiles then one can be sure that the |
|---|
| 35 | concepts cover the component. |
|---|
| 36 | |
|---|
| 37 | The following code shows the archetype class for the <a |
|---|
| 38 | href="http://www.sgi.com/tech/stl/InputIterator.html">Input |
|---|
| 39 | Iterator</a> concept. Some care must be taken to ensure that the |
|---|
| 40 | archetype is an exact match to the concept. For example, the concept |
|---|
| 41 | states that the return type of <tt>operator*()</tt> must be |
|---|
| 42 | convertible to the value type. It does not state the more stringent |
|---|
| 43 | requirement that the return type be <tt>T&</tt> or <tt>const |
|---|
| 44 | T&</tt>. That means it would be a mistake to use <tt>T&</tt> |
|---|
| 45 | or <tt>const T&</tt> for the return type of the archetype |
|---|
| 46 | class. The correct approach is to create an artificial return type |
|---|
| 47 | that is convertible to <tt>T</tt>, as we have done here with |
|---|
| 48 | <tt>reference</tt>. The validity of the archetype class test is |
|---|
| 49 | completely dependent on it being an exact match with the concept, |
|---|
| 50 | which must be verified by careful (manual) inspection. |
|---|
| 51 | |
|---|
| 52 | <pre> |
|---|
| 53 | template <class T> |
|---|
| 54 | class input_iterator_archetype |
|---|
| 55 | { |
|---|
| 56 | private: |
|---|
| 57 | typedef input_iterator_archetype self; |
|---|
| 58 | public: |
|---|
| 59 | typedef std::input_iterator_tag iterator_category; |
|---|
| 60 | typedef T value_type; |
|---|
| 61 | struct reference { |
|---|
| 62 | operator const value_type&() const { return static_object<T>::get(); } |
|---|
| 63 | }; |
|---|
| 64 | typedef const T* pointer; |
|---|
| 65 | typedef std::ptrdiff_t difference_type; |
|---|
| 66 | self& operator=(const self&) { return *this; } |
|---|
| 67 | bool operator==(const self&) const { return true; } |
|---|
| 68 | bool operator!=(const self&) const { return true; } |
|---|
| 69 | reference operator*() const { return reference(); } |
|---|
| 70 | self& operator++() { return *this; } |
|---|
| 71 | self operator++(int) { return *this; } |
|---|
| 72 | }; |
|---|
| 73 | </pre> |
|---|
| 74 | |
|---|
| 75 | Generic algorithms are often tested by being instantiated with a |
|---|
| 76 | number of common input types. For example, one might apply |
|---|
| 77 | <tt>std::stable_sort()</tt> with basic pointer types as the iterators. |
|---|
| 78 | Though appropriate for testing the run-time behavior of the algorithm, |
|---|
| 79 | this is not helpful for ensuring concept coverage because C++ types |
|---|
| 80 | never match particular concepts, they often provide much more than the |
|---|
| 81 | minimal functionality required by any one concept. That is, even |
|---|
| 82 | though the function template compiles with a given type, the concept |
|---|
| 83 | requirements may still fall short of covering the functions actual |
|---|
| 84 | requirements. This is why it is important to compile with archetype |
|---|
| 85 | classes in addition to testing with common input types. |
|---|
| 86 | |
|---|
| 87 | <p> |
|---|
| 88 | The following is an excerpt from <a |
|---|
| 89 | href="./stl_concept_covering.cpp"><tt>stl_concept_covering.cpp</tt></a> |
|---|
| 90 | that shows how archetypes can be used to check the requirement |
|---|
| 91 | documentation for |
|---|
| 92 | <a href="http://www.sgi.com/tech/stl/stable_sort.html"> |
|---|
| 93 | <tt>std::stable_sort()</tt></a>. In this case, it looks like the <a |
|---|
| 94 | href="../utility/CopyConstructible.html">CopyConstructible</a> and <a |
|---|
| 95 | href="../utility/Assignable.html">Assignable</a> requirements were |
|---|
| 96 | forgotten in the SGI STL documentation (try removing those |
|---|
| 97 | archetypes). The Boost archetype classes have been designed so that |
|---|
| 98 | they can be layered. In this example the value type of the iterator |
|---|
| 99 | is composed out of three archetypes. In the archetype class reference |
|---|
| 100 | below, template parameters named <tt>Base</tt> indicate where the |
|---|
| 101 | layered archetype can be used. |
|---|
| 102 | |
|---|
| 103 | <pre> |
|---|
| 104 | { |
|---|
| 105 | typedef less_than_comparable_archetype< |
|---|
| 106 | sgi_assignable_archetype<> > ValueType; |
|---|
| 107 | random_access_iterator_archetype<ValueType> ri; |
|---|
| 108 | std::stable_sort(ri, ri); |
|---|
| 109 | } |
|---|
| 110 | </pre> |
|---|
| 111 | |
|---|
| 112 | <a href="./prog_with_concepts.htm">Next: Programming with Concepts</a><br> |
|---|
| 113 | <a href="./creating_concepts.htm">Prev: Creating Concept Checking Classes</a> |
|---|
| 114 | |
|---|
| 115 | <br> |
|---|
| 116 | <HR> |
|---|
| 117 | <TABLE> |
|---|
| 118 | <TR valign=top> |
|---|
| 119 | <TD nowrap>Copyright © 2000</TD><TD> |
|---|
| 120 | <A HREF="../../people/jeremy_siek.htm">Jeremy Siek</A>(<A |
|---|
| 121 | HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>) |
|---|
| 122 | Andrew Lumsdaine</A>(<A HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>) |
|---|
| 123 | </TD></TR></TABLE> |
|---|
| 124 | |
|---|
| 125 | </BODY> |
|---|
| 126 | </HTML> |
|---|