mirror of
https://github.com/boostorg/concept_check.git
synced 2026-01-31 08:02:16 +00:00
112 lines
4.3 KiB
HTML
112 lines
4.3 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>Creating Concept Checking Classes</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="creating-concept-checks">Creating Concept Checking Classes</a></h2>
|
|
|
|
As an example of how to create a concept checking class, we look
|
|
at how to create the corresponding checks for the
|
|
<a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
|
|
RandomAccessIterator</a> concept. First, as a convention we name the
|
|
concept checking class after the concept, and add the suffix
|
|
``<tt>Concept</tt>''. Next we must define a member function named
|
|
<tt>constraints()</tt> in which we will exercise the valid expressions
|
|
of the concept. <tt>function_requires()</tt> expects this function's
|
|
signature to appear exactly as it is appears below: a <tt>void</tt>
|
|
non-const member function with no parameters.
|
|
|
|
<p>
|
|
The first part of the <tt>constraints()</tt> function includes
|
|
the requirements that correspond to the <i>refinement</i> relationship
|
|
between <a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
|
|
RandomAccessIterator</a> and the concepts which it builds upon:
|
|
<a href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">
|
|
BidirectionalIterator</a> and
|
|
<a href="http://www.sgi.com/Technology/STL/LessThanComparable.html">
|
|
LessThanComparable</a>. We could have instead used
|
|
<tt>BOOST_CLASS_REQUIRES</tt> and placed these requirements in the class
|
|
body, however <tt>BOOST_CLASS_REQUIRES</tt> uses C++ language features that
|
|
are less portable.
|
|
|
|
<p>
|
|
Next we check that the <tt>iterator_category</tt> of the iterator is
|
|
either <tt>std::random_access_iterator_tag</tt> or a derived class.
|
|
After that we write out some code that corresponds to the valid
|
|
expressions of the <a
|
|
href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
|
|
RandomAccessIterator</a> concept. Typedefs can also be added to
|
|
enforce the associated types of the concept.
|
|
|
|
<pre>
|
|
template <class Iter>
|
|
struct RandomAccessIterator_concept
|
|
{
|
|
void constraints() {
|
|
function_requires< BidirectionalIteratorConcept<Iter> >();
|
|
function_requires< LessThanComparableConcept<Iter> >();
|
|
function_requires< ConvertibleConcept<
|
|
typename std::iterator_traits<Iter>::iterator_category,
|
|
std::random_access_iterator_tag> >();
|
|
|
|
i += n;
|
|
i = i + n; i = n + i;
|
|
i -= n;
|
|
i = i - n;
|
|
n = i - j;
|
|
i[n];
|
|
}
|
|
Iter a, b;
|
|
Iter i, j;
|
|
typename std::iterator_traits<Iter>::difference_type n;
|
|
};
|
|
}
|
|
</pre>
|
|
|
|
One potential pitfall in designing concept checking classes is using
|
|
more expressions in the constraint function than necessary. For
|
|
example, it is easy to accidentally use the default constructor to
|
|
create the objects that will be needed in the expressions (and not all
|
|
concepts require a default constructor). This is the reason we write
|
|
the constraint function as a member function of a class. The objects
|
|
involved in the expressions are declared as data members of the class.
|
|
Since objects of the constraints class template are never
|
|
instantiated, the default constructor for the concept checking class
|
|
is never instantiated. Hence the data member's default constructors
|
|
are never instantiated (C++ Standard Section 14.7.1 9).
|
|
|
|
<p>
|
|
<a href="./concept_covering.htm">Next: Concept Covering and Archetypes</a><br>
|
|
<a href="./using_concept_check.htm">Prev: Using Concept Checks</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>
|