diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/concept_check/implementation.htm | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/concept_check/implementation.htm')
-rw-r--r-- | src/boost/libs/concept_check/implementation.htm | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/boost/libs/concept_check/implementation.htm b/src/boost/libs/concept_check/implementation.htm new file mode 100644 index 000000000..e9db3bf65 --- /dev/null +++ b/src/boost/libs/concept_check/implementation.htm @@ -0,0 +1,205 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000, David Abrahams 2007 --> +<!-- Distributed under the Boost --> +<!-- Software License, Version 1.0. (See accompanying --> +<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> + +<head> + <meta name="generator" content= + "HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="../../rst.css" type="text/css" /> + + <title>Concept Checking Implementation</title> +</head> + +<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink= +"#FF0000"> + <img src="../../boost.png" alt="C++ Boost" width="277" height= + "86" /><br clear="none" /> + + <h2><a name="warning" id="warning"><font color= + "red">Warning</font></a></h2> + + <p><font color="red">This documentation is out-of-date; similar but + newer implementation techniques are now used. This documentation + also refers to components and protocols in the library's old + interface such as <code>BOOST_CLASS_REQUIRES</code> + and <code>constraints()</code> functions, which are still supported + but deprecated.</font></p> + + <h2><a name="implementation" id="implementation">Implementation</a></h2> + + <p>Ideally we would like to catch, and indicate, the concept violation at + the point of instantiation. As mentioned in D&E[<a href= + "bibliography.htm#stroustrup94:_design_evolution">2</a>], the error can be + caught by exercising all of the requirements needed by the function + template. Exactly how the requirements (the valid expressions in + particular) are exercised is a tricky issue, since we want the code to be + compiled—<i>but not executed</i>. Our approach is to exercise the + requirements in a separate function that is assigned to a function pointer. + In this case, the compiler will instantiate the function but will not + actually invoke it. In addition, an optimizing compiler will remove the + pointer assignment as ``dead code'' (though the run-time overhead added by + the assignment would be trivial in any case). It might be conceivable for a + compiler to skip the semantic analysis and compilation of the constraints + function in the first place, which would make our function pointer + technique ineffective. However, this is unlikely because removal of + unnecessary code and functions is typically done in later stages of a + compiler. We have successfully used the function pointer technique with GNU + C++, Microsoft Visual C++, and several EDG-based compilers (KAI C++, SGI + MIPSpro). The following code shows how this technique can be applied to the + <tt>std::stable_sort()</tt> function:</p> + <pre> + template <class RandomAccessIterator> + 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) + { + typedef void (*fptr_type)(RandomAccessIterator); + fptr_type x = &stable_sort_constraints; + ... + } +</pre> + + <p>There is often a large set of requirements that need to be checked, and + it would be cumbersome for the library implementor to write constraint + functions like <tt>stable_sort_constraints()</tt> for every public + function. Instead, we group sets of valid expressions together, according + to the definitions of the corresponding concepts. For each concept we + define a concept checking class template where the template parameter is + for the type to be checked. The class contains a <tt>constraints()</tt> + member function which exercises all of the valid expressions of the + concept. The objects used in the constraints function, such as <tt>n</tt> + and <tt>i</tt>, are declared as data members of the concept checking + class.</p> + <pre> + template <class Iter> + struct RandomAccessIteratorConcept + { + void constraints() + { + i += n; + ... + } + typename std::iterator_traits<RandomAccessIterator> + ::difference_type n; + Iter i; + ... + }; +</pre> + + <p>We can still use the function pointer mechanism to cause instantiation + of the constraints function, however now it will be a member function + pointer. To make it easy for the library implementor to invoke the concept + checks, we wrap the member function pointer mechanism in a function named + <tt>function_requires()</tt>. The following code snippet shows how to use + <tt>function_requires()</tt> to make sure that the iterator is a <a href= + "http://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>.</p> + <pre> + template <class Iter> + void stable_sort(Iter first, Iter last) + { + function_requires< RandomAccessIteratorConcept<Iter> >(); + ... + } +</pre> + + <p>The definition of the <tt>function_requires()</tt> is as follows. The + <tt>Concept</tt> is the concept checking class that has been instantiated + with the modeling type. We assign the address of the constraints member + function to the function pointer <tt>x</tt>, which causes the instantiation + of the constraints function and checking of the concept's valid + expressions. We then assign <tt>x</tt> to <tt>x</tt> to avoid unused + variable compiler warnings, and wrap everything in a do-while loop to + prevent name collisions.</p> + <pre> + template <class Concept> + void function_requires() + { + void (Concept::*x)() = BOOST_FPTR Concept::constraints; + ignore_unused_variable_warning(x); + } +</pre> + + <p>To check the type parameters of class templates, we provide the + <tt>BOOST_CLASS_REQUIRE</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.</p> + <pre> +#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + typedef void (ns::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 ns::concept<type_var>::constraints> \ + concept_checking_typedef_##type_var##concept +</pre> + + <p>In addition, there are versions of <tt>BOOST_CLASS_REQUIRE</tt> that + take more arguments, to handle concepts that include interactions between + two or more types. <tt>BOOST_CLASS_REQUIRE</tt> was not used in the + implementation of the BCCL concept checks because some 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 +used inside of a function body). <tt>class_requires</tt> 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. + +<pre> + template <class Concept> + class class_requires + { + typedef void (Concept::* function_pointer)(); + + template <function_pointer Fptr> + struct dummy_struct { }; + public: + typedef dummy_struct< BOOST_FPTR Concept::constraints > check; + }; +</pre> + +<tt>class_requires</tt> was not used in the implementation of the +Boost Concept Checking Library concept checks because several +compilers do not implement template parameters of function pointer +type. + +--></p> + + <p><a href="./reference.htm">Next: Reference</a><br /> + <a href="prog_with_concepts.htm">Prev: Programming With + Concepts</a><br /></p> + <hr /> + + <table> + <tr valign="top"> + <td nowrap="nowrap">Copyright © 2000</td> + + <td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href= + "mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew + Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>), + 2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>. + </tr> + </table> +</body> +</html> |