mirror of
https://github.com/boostorg/concept_check.git
synced 2026-01-26 16:52:19 +01:00
226 lines
7.6 KiB
HTML
226 lines
7.6 KiB
HTML
<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/Technology/STL/EqualityComparable.html">EqualityComparable</a>
|
|
concept documented in the SGI STL.
|
|
|
|
<pre>
|
|
template <class T>
|
|
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 <class T>
|
|
void generic_library_function(T x)
|
|
{
|
|
function_requires< EqualityComparableConcept<T> >();
|
|
// ...
|
|
};
|
|
|
|
// 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 <class T>
|
|
struct generic_library_class
|
|
{
|
|
BOOST_CLASS_REQUIRES(T, EqualityComparableConcept);
|
|
// ...
|
|
};
|
|
|
|
// In the user's code:
|
|
class foo {
|
|
//...
|
|
};
|
|
|
|
int main() {
|
|
generic_library_class<foo> 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/Technology/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/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a>, so we also use <tt>function_requires()</tt> to
|
|
check this.
|
|
|
|
<pre>
|
|
template <class RandomAccessIter>
|
|
void stable_sort(RandomAccessIter first, RandomAccessIter last)
|
|
{
|
|
function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();
|
|
typedef typename std::iterator_traits<RandomAccessIter>::value_type value_type;
|
|
function_requires< LessThanComparableConcept<value_type> >();
|
|
...
|
|
}
|
|
</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 <class IncidenceGraph, class Buffer, class BFSVisitor,
|
|
class ColorMap>
|
|
void breadth_first_search(IncidenceGraph& g,
|
|
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
|
|
Buffer& Q, BFSVisitor vis, ColorMap color)
|
|
{
|
|
typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
|
|
function_requires< ReadWritePropertyMap<ColorMap, Vertex> >();
|
|
...
|
|
}
|
|
</pre>
|
|
|
|
|
|
As an example of using <tt>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/Technology/STL/Assignable.html">Assignable</a>.
|
|
We can check this by inserting
|
|
<tt>class_requires<AssignableConcept<T> ></tt> at the top
|
|
of the definition for <tt>std::vector</tt>.
|
|
|
|
<pre>
|
|
namespace std {
|
|
template <class T>
|
|
struct vector {
|
|
typedef typename class_requires< AssignableConcept<T> >::check req;
|
|
...
|
|
};
|
|
}
|
|
</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 © 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>
|