<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/tech/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/tech/stl/RandomAccessIterator.html"> RandomAccessIterator</a> and the concepts which it builds upon: <a href="http://www.sgi.com/tech/stl/BidirectionalIterator.html"> BidirectionalIterator</a> and <a href="http://www.sgi.com/tech/stl/LessThanComparable.html"> LessThanComparable</a>. We could have instead used <tt>BOOST_CLASS_REQUIRE</tt> and placed these requirements in the class body, however <tt>BOOST_CLASS_REQUIRE</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/tech/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 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>(<A HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>) Andrew Lumsdaine</A>(<A HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>) </TD></TR></TABLE> </BODY> </HTML>