File: using_concept_check.htm

package info (click to toggle)
boost 1.27.0-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 19,908 kB
  • ctags: 26,546
  • sloc: cpp: 122,225; ansic: 10,956; python: 4,412; sh: 855; yacc: 803; makefile: 257; perl: 165; lex: 90; csh: 6
file content (225 lines) | stat: -rw-r--r-- 7,737 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<HTML>
<!--
  -- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000
  --
  -- Permission to use, copy, modify, distribute and sell this software
  -- and its documentation for any purpose is hereby granted without fee,
  -- provided that the above copyright notice appears in all copies and
  -- that both that copyright notice and this permission notice appear
  -- in supporting documentation.  We make no
  -- representations about the suitability of this software for any
  -- purpose.  It is provided "as is" without express or implied warranty.
  -->
<Head>
<Title>Using Concept Checks</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" 
        ALINK="#ff0000"> 
<IMG SRC="../../c++boost.gif" 
     ALT="C++ Boost" width="277" height="86"> 

<BR Clear>


<h2><a name="using-concept-checks">Using Concept Checks</a></h2>

For each concept there is a concept checking class which can be used
to make sure that a given type (or set of types) models the concept.
The Boost Concept Checking Library (BCCL) includes concept checking classes
for all of the concepts used in the C++ standard library and a few
more. The <a href="./reference.htm">Reference</a> section lists these
concept checking classes. In addition, other boost libraries come with
concept checking classes for the concepts that are particular to those
libraries. For example, there are <a
href="../graph/doc/graph_concepts.html">graph concepts</a> and <a
href="../property_map/property_map.html">property map concepts</a>.
Also, whenever <b>anyone</b> writing a class of function template
needs to express requirements that are not yet stated by an existing
concept, a new concept checking class should be created. How
to do this is explained in <a href="./creating_concepts.htm">Creating
Concept Checking Classes</a>.

<p>
An example of a concept checking class from the BCCL is the
<tt>EqualityComparableConcept</tt> class. The class corresponds to the
EqualityComparable requirements described in 20.1.1 of the C++
Standard, and to the <a
href="http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>
concept documented in the SGI STL.

<pre>
  template &lt;class T&gt;
  struct EqualityComparableConcept;
</pre>

The template argument <tt>T</tt> will the type to be checked. That is,
the purpose of <tt>EqualityComparableConcept</tt> is to make sure that
the template argument given for <tt>T</tt> models the
EqualityComparable concept.

<p>
Each concept checking class has a member function named
<tt>constraints()</tt> which contains the valid expressions for the
concept. To check whether some type is EqualityComparable we need to
instantiate the concept checking class with the type and then find a
way to get the compiler to compile the <tt>constraints()</tt> function
without actually executing the function. The Boost Concept Checking
Library defines two utilities that make this easy:
<tt>function_requires()</tt> and <tt>BOOST_CLASS_REQUIRES</tt>.

<h4><tt>function_requires()</tt></h4>

The <tt>function_requires()</tt> function can be used in function bodies
and the <tt>BOOST_CLASS_REQUIRES</tt> macro can be used inside class
bodies. The <tt>function_requires()</tt> function takes no arguments,
but has a template parameter for the concept checking class. This
means that the instantiated concept checking class must be given as an
explicit template argument, as shown below.

<pre>
  // In my library:
  template &lt;class T&gt;
  void generic_library_function(T x)
  {
    function_requires&lt; EqualityComparableConcept&lt;T&gt; &gt;();
    // ...
  };

  // In the user's code:  
  class foo {
    //... 
  };

  int main() {
    foo f;
    generic_library_function(f);
    return 0;
  }
</pre>


<h4><tt>BOOST_CLASS_REQUIRES</tt></h4>

The <tt>BOOST_CLASS_REQUIRES</tt> macro can be used inside a class
definition to check whether some type models a concept. 

<pre>
  // In my library:
  template &lt;class T&gt;
  struct generic_library_class
  {
    BOOST_CLASS_REQUIRES(T, EqualityComparableConcept);
    // ...
  };

  // In the user's code:  
  class foo {
    //... 
  };

  int main() {
    generic_library_class&lt;foo&gt; glc;
    // ...
    return 0;
  }
</pre>


<h4>Example</h4>

<p>
Getting back to the earlier <a
href="./concept_check.htm#motivating-example">motivating example</a>,
one good applicatino of concept checks would be to insert
<tt>function_requires()</tt> at the top of <tt>std::stable_sort()</tt>
to make sure the template parameter type models <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">
RandomAccessIterator</a>. In addition, <tt>std::stable_sort()</tt>
requires that the <tt>value_type</tt> of the iterators be
<a href="http://www.sgi.com/tech/stl/LessThanComparable.html">
LessThanComparable</a>, so we also use <tt>function_requires()</tt> to
check this.

<pre>
  template &lt;class RandomAccessIter&gt;
  void stable_sort(RandomAccessIter first, RandomAccessIter last)
  {
    function_requires&lt; RandomAccessIteratorConcept&lt;RandomAccessIter&gt; &gt;();
    typedef typename std::iterator_traits&lt;RandomAccessIter&gt;::value_type value_type;
    function_requires&lt; LessThanComparableConcept&lt;value_type&gt; &gt;();
    ...
  }
</pre>



<!-- There are a few places where the SGI STL documentation differs
from the corresponding requirements described in the C++ Standard. In
these cases we use the definition from the C++ Standard.  -->

<p>
Some concepts deal with more than one type. In this case the
corresponding concept checking class will have multiple template
parameters.  The following example shows how
<tt>function_requires()</tt> is used with the <a
href="../property_map/ReadWritePropertyMap.html">ReadWritePropertyMap</a>
concept which takes two type parameters: a property map and the key
type for the map.

<pre>
  template &lt;class IncidenceGraph, class Buffer, class BFSVisitor, 
            class ColorMap&gt;
  void breadth_first_search(IncidenceGraph& g, 
    typename graph_traits&lt;IncidenceGraph&gt;::vertex_descriptor s, 
    Buffer& Q, BFSVisitor vis, ColorMap color)
  {
    typedef typename graph_traits&lt;IncidenceGraph&gt;::vertex_descriptor Vertex;
    function_requires&lt; ReadWritePropertyMap&lt;ColorMap, Vertex&gt; &gt;();
    ...
  }
</pre>


As an example of using <tt>BOOST_CLASS_REQUIRES</tt> we look at a concept
check that could be added to <tt>std::vector</tt>. One requirement
that is placed on the element type is that it must be <a
href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.
We can check this by inserting
<tt>class_requires&lt;AssignableConcept&lt;T&gt; &gt;</tt> at the top
of the definition for <tt>std::vector</tt>.

<pre>
  namespace std {
    template &lt;class T&gt;
    struct vector {
      BOOST_CLASS_REQUIRES(T, AssignableConcept);
      ...
    };
  }
</pre>


Although the concept checks are designed for use by generic library
implementors, they can also be useful to end users. Sometimes one may
not be sure whether some type models a particular concept. This can
easily be checked by creating a small program and using
<tt>function_requires()</tt> with the type and concept in question.
The file <a
href="./stl_concept_check.cpp"><tt>stl_concept_checks.cpp</tt></a>
gives and example of applying the concept checks to STL containers.

<p>
<a href="./concept_check.htm">Prev: Concept Checking Introduction</a> <br>
<a href="./creating_concepts.htm">Next: Creating Concept Checking Classes</a>

<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF="../../people/jeremy_siek.htm">Jeremy Siek</A>,
Univ.of Notre Dame (<A
HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
</TD></TR></TABLE>

</BODY>
</HTML>