forked from boostorg/concept_check
more reorganization and editing of the concept docs
[SVN r8437]
This commit is contained in:
@@ -24,35 +24,87 @@
|
||||
<h2>
|
||||
<A NAME="sec:concept-checking"></A>
|
||||
header <a href="../../boost/concept_check.hpp">
|
||||
<tt>boost/concept_check.hpp</tt></a> and <a href="../../boost/concept_archetype.hpp">
|
||||
<tt>boost/concept_check.hpp</tt></a>
|
||||
<br>and <a href="../../boost/concept_archetype.hpp">
|
||||
<tt>boost/concept_archetype.hpp</tt></a>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Generic programming in C++ is characterized by the use of template
|
||||
parameters to represent abstract data types (or ``concepts'').
|
||||
However, the C++ language itself does not provide a mechanism for
|
||||
explicitly handling concepts. As a result, it can be difficult to
|
||||
insure that a concrete type meets the requirements of the concept it
|
||||
is supposed to represent. Error messages resulting from incorrect use
|
||||
of a concrete type can be particularly difficult to decipher. The
|
||||
Boost Concept Checking Library provides mechanisms for checking
|
||||
parameters in C++ template libraries. The mechanisms use standard C++
|
||||
and introduce no run-time overhead. The main cost of using the
|
||||
mechanism is in compile-time.
|
||||
However, the C++ language itself does not provide a mechanism for the
|
||||
writer of a class or function template to explicitly state what
|
||||
concept the user-supplied template argument should model (or conform
|
||||
to). The common practice is to name the template parameter after the
|
||||
required concept as a hint to the user and to state the concept
|
||||
requirements in the documentation. However, often times the
|
||||
requirements are vague, incorrect, or nonexistent, which is quite a
|
||||
problem for the user, since he or she will not know exactly what kind
|
||||
of input is expected by the template. Furthemore, the following
|
||||
problems occur:
|
||||
|
||||
<ul>
|
||||
<li>Compiler error messages resulting from incorrect template
|
||||
arguments can be particularly difficult to decipher. Often times
|
||||
the error does not point to the location of the template
|
||||
call-site, but instead exposes the internals of the template, which
|
||||
the user should never have to see.</li>
|
||||
|
||||
<li>The documented concept requirements may not fully <i>cover</i>
|
||||
the template, meaning the user could get a compiler error even
|
||||
though the supplied template arguments meet the documented
|
||||
requirements.</li>
|
||||
|
||||
<li>The documented concept requirements may be too stringent,
|
||||
requiring more than is really needed by the template.</li>
|
||||
|
||||
<li>The requirements are not explicitly stated in the code, which
|
||||
makes the code harder to understand. Also, the code may
|
||||
get out-of-sync with the documented requirements.</li>
|
||||
</ul>
|
||||
|
||||
The Boost Concept Checking Library provides:
|
||||
|
||||
<ul>
|
||||
<li>A mechanism for inserting compile-time checks of template
|
||||
parameters.</li>
|
||||
|
||||
<li>A framework for specifying concept requirements though <i>concept
|
||||
checking classes</i>.</li>
|
||||
|
||||
<li>Verify that concept requirements cover the template.</li>
|
||||
|
||||
<li>A suite of concept checking classes and archetype classes that
|
||||
match the concept requirements in the C++ Standard Library.</li>
|
||||
</ul>
|
||||
|
||||
The mechanisms use standard C++ and introduce no run-time
|
||||
overhead. The main cost of using the mechanism is in compile-time.
|
||||
|
||||
<p>
|
||||
Any programmer writing class or function templates ought to make
|
||||
concept checking a normal part of their code-writing routine. A
|
||||
concept check should be inserted for each template paramter in a
|
||||
component's public interface. If the concept is one of the ones from
|
||||
the Standard Library, then simply use the matching concept checking
|
||||
class in the BCCL. If not, then write a new concept checking class -
|
||||
after all, they are typically only a few lines long. For new concepts,
|
||||
a matching archetype class should also be created, which is a minimal
|
||||
skeleton-implementation of the concept
|
||||
|
||||
<p>
|
||||
The documentation is organized into the following sections.
|
||||
|
||||
<OL>
|
||||
<LI><a href="#introduction">Introduction</a></LI>
|
||||
<LI><a href="#motivating-example">Motivating Example</a></LI>
|
||||
<LI><a href="./using_concept_checks.htm">Using Concept Checks</a></LI>
|
||||
<LI><a href="./using_concept_check.htm">Using Concept Checks</a></LI>
|
||||
<LI><a href="./creating_concept_checks.htm">Creating Concept Checking Classes</a></LI>
|
||||
<LI><a href="./concept_covering.htm">Concept Covering and Archetypes</a></LI>
|
||||
<LI><a href="./prog_with_concepts.htm"">Programming With Concepts</a></LI>
|
||||
<LI><a href="./implementation.htm">Implementation</a></LI>
|
||||
<LI><a href="./reference.htm">Reference</a></LI>
|
||||
<LI><a href="./history.htm">History</a></LI>
|
||||
<LI><a href="#history">History</a></LI>
|
||||
<LI><a href="#publications">Publications</a></LI>
|
||||
<LI><a href="#acknowledgements">Acknowledgements</a></LI>
|
||||
</OL>
|
||||
@@ -186,14 +238,14 @@ informative message (and is in fact what the Boost Concept Checking
|
||||
Library produces):
|
||||
|
||||
<pre>
|
||||
concept_check.hpp: In method `void LessThanComparable_concept
|
||||
boost/concept_check.hpp: In method `void LessThanComparableConcept
|
||||
<_List_iterator<foo,foo &,foo *> >::constraints()':
|
||||
concept_check.hpp:334: instantiated from `RandomAccessIterator_concept
|
||||
boost/concept_check.hpp:334: instantiated from `RandomAccessIteratorConcept
|
||||
<_List_iterator<foo,foo &,foo *> >::constraints()'
|
||||
bad_error_eg.cpp:9: instantiated from `stable_sort<_List_iterator
|
||||
<foo,foo &,foo *> >(_List_iterator<foo,foo &,foo *>,
|
||||
_List_iterator<foo,foo &,foo *>)'
|
||||
concept_check.hpp:209: no match for `_List_iterator<foo,foo &,foo *> &
|
||||
boost/concept_check.hpp:209: no match for `_List_iterator<foo,foo &,foo *> &
|
||||
< _List_iterator<foo,foo &,foo *> &'
|
||||
</pre>
|
||||
|
||||
@@ -215,14 +267,45 @@ RandomAccessIterator</a>).
|
||||
implementation.
|
||||
</UL>
|
||||
|
||||
<h2><a name="history">History</a></h2>
|
||||
|
||||
An earlier version of this concept checking system was developed by
|
||||
the author while working at SGI in their C++ compiler and library
|
||||
group. The earlier version is now part of the SGI STL distribution. The
|
||||
boost concept checking library differs from the concept checking in
|
||||
the SGI STL in that the definition of concept checking classes has
|
||||
been greatly simplified, at the price of less helpful verbiage in the
|
||||
error messages.
|
||||
|
||||
<h2><a name="publications">Publications</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://www.oonumerics.org/tmpw00/">
|
||||
C++ Template Workshop 2000</a>, Concept Checking</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="acknowledgements">Acknowledgements</a></h2>
|
||||
|
||||
The idea to use function pointers to cause instantiation is due to
|
||||
Alexander Stepanov. I am not sure of the origin of the idea to use
|
||||
expressions to do up-front checking of templates, but it did appear in
|
||||
D&E[
|
||||
<a href="bibliography.html#stroustrup94:_design_evolution">2</a>].
|
||||
Thanks to Matt Austern for his excellent documentation and
|
||||
organization of the STL concepts, upon which these concept checks
|
||||
are based. Thanks to Boost members for helpful comments and
|
||||
reviews.
|
||||
|
||||
|
||||
<p>
|
||||
<a href="./using_concept_check.htm">Next: 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="../../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>
|
||||
|
@@ -1,3 +1,23 @@
|
||||
<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>Concept Covering and Archetypes</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="concept-covering">Concept Covering and Archetypes</a></h2>
|
||||
|
||||
@@ -94,3 +114,18 @@ layered archetype can be used.
|
||||
}
|
||||
</pre>
|
||||
|
||||
<a href="./prog_with_concepts.htm">Next: Programming with Concepts</a><br>
|
||||
<a href="./creating_concepts.htm">Prev: 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>
|
||||
|
@@ -1,3 +1,25 @@
|
||||
<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
|
||||
@@ -70,3 +92,21 @@ 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>
|
||||
|
@@ -1,3 +1,23 @@
|
||||
<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>Concept Checking Implementation</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="implementation">Implementation</a></h2>
|
||||
@@ -26,14 +46,16 @@ can be applied to the <tt>std::stable_sort()</tt> function:
|
||||
|
||||
<pre>
|
||||
template <class RandomAccessIterator>
|
||||
void stable_sort_constraints(RandomAccessIterator i) {
|
||||
void stable_sort_constraints(RandomAccessIterator i)
|
||||
{
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::difference_type n;
|
||||
i += n; // exercise the requirements for RandomAccessIterator
|
||||
...
|
||||
}
|
||||
template <class RandomAccessIterator>
|
||||
void stable_sort(RandomAccessIterator first, RandomAccessIterator last) {
|
||||
void stable_sort(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
typedef void (*fptr_type)(RandomAccessIterator);
|
||||
fptr_type x = &stable_sort_constraints;
|
||||
...
|
||||
@@ -54,8 +76,10 @@ members of the concept checking class.
|
||||
|
||||
<pre>
|
||||
template <class Iter>
|
||||
struct RandomAccessIterator_concept {
|
||||
void constraints() {
|
||||
struct RandomAccessIterator_concept
|
||||
{
|
||||
void constraints()
|
||||
{
|
||||
i += n;
|
||||
...
|
||||
}
|
||||
@@ -78,10 +102,10 @@ href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
|
||||
RandomAccessIterator</a>.
|
||||
|
||||
<pre>
|
||||
template <class RandomAccessIter>
|
||||
void stable_sort(RandomAccessIter first, RandomAccessIter last)
|
||||
template <class Iter>
|
||||
void stable_sort(Iter first, Iter last)
|
||||
{
|
||||
function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();
|
||||
function_requires< RandomAccessIteratorConcept<Iter> >();
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
@@ -96,7 +120,7 @@ the concept's valid expressions. We then assign <tt>x</tt> to
|
||||
everything in a do-while loop to prevent name collisions.
|
||||
|
||||
<pre>
|
||||
template <class Concept>
|
||||
template <class Concept>
|
||||
void function_requires()
|
||||
{
|
||||
void (Concept::*x)() = BOOST_FPTR Concept::constraints;
|
||||
@@ -104,6 +128,36 @@ everything in a do-while loop to prevent name collisions.
|
||||
}
|
||||
</pre>
|
||||
|
||||
To check the type parameters of class templates, we provide the
|
||||
<tt>BOOST_CLASS_REQUIRES</tt> macro which can be used inside the body of a
|
||||
class definition (whereas <tt>function_requires()</tt> can only be used
|
||||
inside of a function body). This macro declares a nested class
|
||||
template, where the template parameter is a function pointer. We then
|
||||
use the nested class type in a typedef with the function pointer type
|
||||
of the constraint function as the template argument. We use the
|
||||
<tt>type_var</tt> and <tt>concept</tt> names in the nested class and
|
||||
typedef names to help prevent name collisions.
|
||||
|
||||
<pre>
|
||||
#define BOOST_CLASS_REQUIRES(type_var, concept) \
|
||||
typedef void (concept <type_var>::* func##type_var##concept)(); \
|
||||
template <func##type_var##concept _Tp1> \
|
||||
struct concept_checking_##type_var##concept { }; \
|
||||
typedef concept_checking_##type_var##concept< \
|
||||
BOOST_FPTR concept <type_var>::constraints> \
|
||||
concept_checking_typedef_##type_var##concept
|
||||
</pre>
|
||||
|
||||
In addition, there are versions of <tt>BOOST_CLASS_REQUIRES</tt> that
|
||||
take more arguments, to handle concepts that include interactions
|
||||
between two or more types. <tt>BOOST_CLASS_REQUIRES</tt> was not used
|
||||
in the implementation of the BCCL concept checks because several
|
||||
compilers do not implement template parameters of function pointer
|
||||
type.
|
||||
|
||||
|
||||
<!-- We decided not to go with this version since it is easier to misuse
|
||||
|
||||
To check the type parameters of class templates, we provide the
|
||||
<tt>class_requires</tt> class which can be used inside the body of a
|
||||
class definition (whereas <tt>function_requires()</tt> can only be
|
||||
@@ -131,3 +185,21 @@ Boost Concept Checking Library concept checks because several
|
||||
compilers do not implement template parameters of function pointer
|
||||
type.
|
||||
|
||||
-->
|
||||
|
||||
<p>
|
||||
<a href="./reference.htm">Next: Reference</a><br>
|
||||
<a href="./prog_with_concepts.html">Prev: Programming With Concepts</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>
|
||||
|
@@ -1,3 +1,23 @@
|
||||
<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>Programming With Concepts</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="programming-with-concepts">Programming with Concepts</a></h2>
|
||||
|
||||
@@ -31,6 +51,9 @@ keep in mind their purpose, namely to express the requirements for the
|
||||
input to the components. With respect to the requirement minimization
|
||||
principle, this means we want to minimize concepts.
|
||||
|
||||
<!-- the following discussion does not match the Standard definition
|
||||
of LessThanComparable and needs to be changed -Jeremy
|
||||
|
||||
<p>
|
||||
It is important to note, however, that
|
||||
minimizing concepts does not mean simply
|
||||
@@ -82,6 +105,8 @@ LessThanComparable</a> is given as the requirement for
|
||||
<tt>std::stable_sort()</tt>, then the maintainer is given a reasonable
|
||||
amount of flexibility within which to work.
|
||||
|
||||
-->
|
||||
|
||||
<p>
|
||||
Minimality in concepts is a property associated with the underlying
|
||||
semantics of the problem domain being represented. In the problem
|
||||
@@ -104,3 +129,20 @@ important to factor families of requirements into rather fine-grained
|
||||
concepts. For example, the requirements for iterators are factored
|
||||
into the six STL iterator concepts (trivial, output, input, forward,
|
||||
bidirectional, and random access).
|
||||
|
||||
<p>
|
||||
<a href="./implementation.htm">Next: Implementation</a><br>
|
||||
<a href="./concept_covering.htm">Prev: Concept Covering and Archetypes</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>
|
||||
|
111
reference.htm
111
reference.htm
@@ -1,9 +1,30 @@
|
||||
<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>Boost Concept Checking Reference</Title>
|
||||
</Head>
|
||||
<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="reference">Reference</a></h2>
|
||||
|
||||
<OL>
|
||||
<LI><a href="#functions">Functions</a></LI>
|
||||
<LI><a href="#classes">Classes</a></LI>
|
||||
<LI><a href="#macros">Macros</a></LI>
|
||||
<LI><a href="#basic-concepts">Basic Concept Checking Classes</a></LI>
|
||||
<LI><a href="#iterator-concepts">Iterator Concept Checking Classes</a></LI>
|
||||
<LI><a href="#function-object-concepts">Function Object Concept Checking Classes</a></LI>
|
||||
@@ -21,55 +42,53 @@
|
||||
void function_requires();
|
||||
</pre>
|
||||
|
||||
<h3><a name="classes">Classes</a></h3>
|
||||
<pre>
|
||||
template <class Concept>
|
||||
struct class_requires {
|
||||
typedef ... check;
|
||||
};
|
||||
</pre>
|
||||
<h3><a name="macros">Macros</a></h3>
|
||||
|
||||
<pre>
|
||||
// Make sure that <i>Type1</i> and <i>Type2</i> are exactly the same type.
|
||||
// If they are not, then the nested typedef for <tt>type</tt> will
|
||||
// not exist and cause a compiler error.
|
||||
template <class Type1, class Type2>
|
||||
struct require_same {
|
||||
typedef ... type;
|
||||
};
|
||||
// usage example
|
||||
typedef typedef require_same<int,int>::type req1; // this will compile OK
|
||||
typedef typedef require_same<int,float>::type req1; // this will cause a compiler error
|
||||
// Apply concept checks in class definitions.
|
||||
BOOST_CLASS_REQUIRES(<i>type</i>, <i>concept</i>);
|
||||
BOOST_CLASS_REQUIRES2(<i>type1</i>, <i>type2</i>, <i>concept</i>);
|
||||
BOOST_CLASS_REQUIRES3(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>concept</i>);
|
||||
BOOST_CLASS_REQUIRES4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>concept</i>);
|
||||
</pre>
|
||||
|
||||
|
||||
<h3><a name="basic-concepts">Basic Concept Checking Classes</a></h3>
|
||||
|
||||
<pre>
|
||||
template <class T> struct Integer_concept; // Is T a built-in integer type?
|
||||
template <class T> struct SignedIntegerConcept; // Is T a built-in signed integer type?
|
||||
template <class X, class Y> struct ConvertibleConcept; // Is X convertible to Y?
|
||||
template <class T> struct AssignableConcept;
|
||||
template <class T> struct DefaultConstructibleConcept;
|
||||
template <class T> struct CopyConstructibleConcept;
|
||||
template <class T> struct BooleanConcept;
|
||||
template <class T> struct EqualityComparableConcept;
|
||||
// Is class T equality comparable on the left side with type Left?
|
||||
template <class T, class Left> struct LeftEqualityComparableConcept;
|
||||
template <class T> struct LessThanComparableConcept;
|
||||
template <class T> struct <a
|
||||
href="../utility/Assignable.html">Assignable</a>Concept; // Standard ref 23.1
|
||||
template <class T> struct SGI<a href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</a>Concept;
|
||||
template <class T> struct <a href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">DefaultConstructible</a>Concept;
|
||||
template <class T> struct <a
|
||||
href="../utility/CopyConstructible.html">CopyConstructible</a>Concept; // Standard ref 20.1.3
|
||||
template <class T> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/EqualityComparable.html">EqualityComparable</a>Concept; // Standard ref 20.1.1
|
||||
template <class T> struct <a
|
||||
href="../utility/LessThanComparable.html">LessThanComparable</a>Concept; // Standard ref 20.1.2
|
||||
template <class T> struct ComparableConcept; // The SGI STL <a href="http://www.sgi.com/Technology/STL/LessThanComparable.html">LessThanComparable</a> concept
|
||||
</pre>
|
||||
|
||||
<h3><a name="iterator-concepts">Iterator Concept Checking Classes</a></h3>
|
||||
|
||||
<pre>
|
||||
template <class Iter> struct TrivialIteratorConcept;
|
||||
template <class Iter> struct <a href="http://www.sgi.com/Technology/STL/trivial.html">TrivialIterator</a>Concept;
|
||||
template <class Iter> struct Mutable_TrivialIteratorConcept;
|
||||
template <class Iter> struct InputIteratorConcept;
|
||||
template <class Iter, class T> struct OutputIteratorConcept;
|
||||
template <class Iter> struct ForwardIteratorConcept;
|
||||
template <class Iter> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</a>Concept; // Standard ref 24.1.1 Table 72
|
||||
template <class Iter, class T> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/OutputIterator.html">OutputIterator</a>Concept; // Standard ref 24.1.2 Table 73
|
||||
template <class Iter> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/ForwardIterator.html">ForwardIterator</a>Concept; // Standard ref 24.1.3 Table 74
|
||||
template <class Iter> struct Mutable_ForwardIteratorConcept;
|
||||
template <class Iter> struct BidirectionalIteratorConcept;
|
||||
template <class Iter> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">BidirectionalIterator</a>Concept; // Standard ref 24.1.4 Table 75
|
||||
template <class Iter> struct Mutable_BidirectionalIteratorConcept;
|
||||
template <class Iter> struct RandomAccessIteratorConcept;
|
||||
template <class Iter> struct <a
|
||||
href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">RandomAccessIterator</a>Concept; // Standard ref 24.1.5 Table 76
|
||||
template <class Iter> struct Mutable_RandomAccessIteratorConcept;
|
||||
</pre>
|
||||
|
||||
@@ -87,23 +106,23 @@
|
||||
<h3><a name="container-concepts">Container Concept Checking Classes</a></h3>
|
||||
|
||||
<pre>
|
||||
template <class C> struct ContainerConcept;
|
||||
template <class C> struct ContainerConcept; // Standard ref 23.1 Table 65
|
||||
template <class C> struct Mutable_ContainerConcept;
|
||||
|
||||
template <class C> struct ForwardContainerConcept;
|
||||
template <class C> struct Mutable_ForwardContainerConcept;
|
||||
|
||||
template <class C> struct ReversibleContainerConcept;
|
||||
template <class C> struct ReversibleContainerConcept; // Standard ref 23.1 Table 66
|
||||
template <class C> struct Mutable_ReversibleContainerConcept;
|
||||
|
||||
template <class C> struct RandomAccessContainerConcept;
|
||||
template <class C> struct Mutable_RandomAccessContainerConcept;
|
||||
|
||||
template <class C> struct SequenceConcept;
|
||||
template <class C> struct SequenceConcept; // Standard ref 23.1.1
|
||||
template <class C> struct FrontInsertionSequenceConcept;
|
||||
template <class C> struct BackInsertionSequenceConcept;
|
||||
|
||||
template <class C> struct AssociativeContainerConcept;
|
||||
template <class C> struct AssociativeContainerConcept; // Standard ref 23.1.2 Table 69
|
||||
template <class C> struct UniqueAssociativeContainerConcept;
|
||||
template <class C> struct MultipleAssociativeContainerConcept;
|
||||
template <class C> struct SimpleAssociativeContainerConcept;
|
||||
@@ -115,11 +134,10 @@
|
||||
<h3><a name="basic-archetype">Basic Archetype Classes</a></h3>
|
||||
|
||||
<pre>
|
||||
class null_archetype; // A type that models no concepts.
|
||||
template <class T = int> class null_archetype; // A type that models no concepts.
|
||||
template <class Base = null_archetype> class default_constructible_archetype;
|
||||
template <class Base = null_archetype> class assignable_archetype;
|
||||
template <class Base = null_archetype> class copy_constructible_archetype;
|
||||
template <class Left, class Base = null_archetype> class left_equality_comparable_archetype;
|
||||
template <class Base = null_archetype> class equality_comparable_archetype;
|
||||
template <class T, class Base = null_archetype> class convertible_to_archetype;
|
||||
</pre>
|
||||
@@ -150,3 +168,20 @@
|
||||
UNDER CONSTRUCTION
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<a href="./concept_check.htm">Back to Introduction</a>
|
||||
<br>
|
||||
<a href="./implementation.htm">Prev: Implementation</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>
|
||||
|
@@ -1,29 +1,74 @@
|
||||
<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 includes concept checking classes
|
||||
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">Reference</a> section below lists these
|
||||
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. An example of one of these classes is the
|
||||
<tt>EqualityComparableConcept</tt> class.
|
||||
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;
|
||||
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, say <tt>foo</tt>, is
|
||||
EqualityComparable, we need to instantiate the concept checking class
|
||||
with foo: <tt>EqualityComparableConcept<foo></tt> and then find
|
||||
a way to get the compiler to compile the <tt>constraints()</tt>
|
||||
function without actually calling it. The Boost Concept Checking
|
||||
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>.
|
||||
<tt>function_requires()</tt> function can be used in function bodies
|
||||
|
||||
<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
|
||||
@@ -31,25 +76,62 @@ means that the instantiated concept checking class must be given as an
|
||||
explicit template argument, as shown below.
|
||||
|
||||
<pre>
|
||||
void some_function_using_foo() {
|
||||
function_requires< EqualityComparableConcept<foo> >();
|
||||
// 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>
|
||||
struct some_class_using_foo {
|
||||
BOOST_CLASS_REQUIRES(foo, EqualityComparableConcept);
|
||||
// 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>
|
||||
|
||||
To add concept checks to the <tt>std::stable_sort()</tt> function the
|
||||
library implementor would simply insert <tt>function_requires()</tt>
|
||||
at the top of <tt>std::stable_sort()</tt> to make sure the template
|
||||
parameter type models <a
|
||||
|
||||
<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
|
||||
@@ -122,60 +204,22 @@ 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_checks.cpp"><tt>stl_concept_checks.cpp</tt></a>
|
||||
gives and example of applying the concept checks to STL
|
||||
containers. The file is listed here:
|
||||
href="./stl_concept_check.cpp"><tt>stl_concept_checks.cpp</tt></a>
|
||||
gives and example of applying the concept checks to STL containers.
|
||||
|
||||
<pre>
|
||||
#include <boost/concept_check.hpp>
|
||||
<p>
|
||||
<a href="./concept_check.htm">Prev: Concept Checking Introduction</a> <br>
|
||||
<a href="./creating_concepts.htm">Next: Creating Concept Checking Classes</a>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef std::vector<int> Vector;
|
||||
typedef std::deque<int> Deque;
|
||||
typedef std::list<int> List;
|
||||
|
||||
function_requires< Mutable_RandomAccessContainer<Vector> >();
|
||||
function_requires< BackInsertionSequence<Vector> >();
|
||||
|
||||
function_requires< Mutable_RandomAccessContainer<Deque> >();
|
||||
function_requires< FrontInsertionSequence<Deque> >();
|
||||
function_requires< BackInsertionSequence<Deque> >();
|
||||
|
||||
function_requires< Mutable_ReversibleContainer<List> >();
|
||||
function_requires< FrontInsertionSequence<List> >();
|
||||
function_requires< BackInsertionSequence<List> >();
|
||||
|
||||
typedef std::set<int> Set;
|
||||
typedef std::multiset<int> MultiSet;
|
||||
typedef std::map<int,int> Map;
|
||||
typedef std::multimap<int,int> MultiMap;
|
||||
|
||||
function_requires< SortedAssociativeContainer<Set> >();
|
||||
function_requires< SimpleAssociativeContainer<Set> >();
|
||||
function_requires< UniqueAssociativeContainer<Set> >();
|
||||
|
||||
function_requires< SortedAssociativeContainer<MultiSet> >();
|
||||
function_requires< SimpleAssociativeContainer<MultiSet> >();
|
||||
function_requires< MultipleAssociativeContainer<MultiSet> >();
|
||||
|
||||
function_requires< SortedAssociativeContainer<Map> >();
|
||||
function_requires< UniqueAssociativeContainer<Map> >();
|
||||
function_requires< PairAssociativeContainer<Map> >();
|
||||
|
||||
function_requires< SortedAssociativeContainer<MultiMap> >();
|
||||
function_requires< MultipleAssociativeContainer<MultiMap> >();
|
||||
function_requires< PairAssociativeContainer<MultiMap> >();
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
<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>
|
||||
|
Reference in New Issue
Block a user