*** empty log message ***

[SVN r15038]
This commit is contained in:
Jeremy Siek
2002-08-21 16:30:48 +00:00
parent 5fface1ce0
commit 2ebed5a25a
8 changed files with 79 additions and 29 deletions

9
Jamfile Normal file
View File

@@ -0,0 +1,9 @@
subproject libs/concept_check ;
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
compile concept_check_test.cpp ;
compile class_concept_check_test.cpp ;
link-fail concept_check_fail_expected.cpp ;
link-fail class_concept_fail_expected.cpp ;

View File

@@ -8,7 +8,7 @@
/* /*
This file verifies that the BOOST_CLASS_REQUIRES macro of the Boost This file verifies that the BOOST_CLASS_REQUIRE macro of the Boost
Concept Checking Library does not cause errors when it is not suppose Concept Checking Library does not cause errors when it is not suppose
to. to.
@@ -17,21 +17,19 @@
struct foo { bool operator()(int) { return true; } }; struct foo { bool operator()(int) { return true; } };
struct bar { bool operator()(int, char) { return true; } }; struct bar { bool operator()(int, char) { return true; } };
using namespace boost;
class class_requires_test class class_requires_test
{ {
BOOST_CLASS_REQUIRES(int, EqualityComparableConcept); BOOST_CLASS_REQUIRE(int, boost, EqualityComparableConcept);
typedef int* int_ptr; typedef const int* const_int_ptr; typedef int* int_ptr; typedef const int* const_int_ptr;
BOOST_CLASS_REQUIRES2(int_ptr, const_int_ptr, EqualOpConcept); BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, boost, EqualOpConcept);
BOOST_CLASS_REQUIRES3(foo, bool, int, UnaryFunctionConcept); BOOST_CLASS_REQUIRE3(foo, bool, int, boost, UnaryFunctionConcept);
BOOST_CLASS_REQUIRES4(bar, bool, int, char, BinaryFunctionConcept); BOOST_CLASS_REQUIRE4(bar, bool, int, char, boost, BinaryFunctionConcept);
}; };
int int
main() main()
{ {
class_requires_test x; class_requires_test x;
ignore_unused_variable_warning(x); boost::ignore_unused_variable_warning(x);
return 0; return 0;
} }

View File

@@ -18,11 +18,9 @@
struct foo { }; struct foo { };
using namespace boost;
class class_requires_test class class_requires_test
{ {
BOOST_CLASS_REQUIRES(foo, EqualityComparableConcept); BOOST_CLASS_REQUIRE(foo, boost, EqualityComparableConcept);
}; };
int int

View File

@@ -42,8 +42,8 @@ RandomAccessIterator</a> and the concepts which it builds upon:
BidirectionalIterator</a> and BidirectionalIterator</a> and
<a href="http://www.sgi.com/tech/stl/LessThanComparable.html"> <a href="http://www.sgi.com/tech/stl/LessThanComparable.html">
LessThanComparable</a>. We could have instead used LessThanComparable</a>. We could have instead used
<tt>BOOST_CLASS_REQUIRES</tt> and placed these requirements in the class <tt>BOOST_CLASS_REQUIRE</tt> and placed these requirements in the class
body, however <tt>BOOST_CLASS_REQUIRES</tt> uses C++ language features that body, however <tt>BOOST_CLASS_REQUIRE</tt> uses C++ language features that
are less portable. are less portable.
<p> <p>

View File

@@ -129,7 +129,7 @@ everything in a do-while loop to prevent name collisions.
</pre> </pre>
To check the type parameters of class templates, we provide the 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 <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 class definition (whereas <tt>function_requires()</tt> can only be used
inside of a function body). This macro declares a nested class inside of a function body). This macro declares a nested class
template, where the template parameter is a function pointer. We then template, where the template parameter is a function pointer. We then
@@ -139,23 +139,22 @@ of the constraint function as the template argument. We use the
typedef names to help prevent name collisions. typedef names to help prevent name collisions.
<pre> <pre>
#define BOOST_CLASS_REQUIRES(type_var, concept) \ #define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
typedef void (concept &lt;type_var&gt;::* func##type_var##concept)(); \ typedef void (ns::concept &lt;type_var&gt;::* func##type_var##concept)(); \
template &lt;func##type_var##concept _Tp1&gt; \ template &lt;func##type_var##concept _Tp1&gt; \
struct concept_checking_##type_var##concept { }; \ struct concept_checking_##type_var##concept { }; \
typedef concept_checking_##type_var##concept&lt; \ typedef concept_checking_##type_var##concept&lt; \
BOOST_FPTR concept &lt;type_var&gt;::constraints&gt; \ BOOST_FPTR ns::concept&lt;type_var&gt;::constraints&gt; \
concept_checking_typedef_##type_var##concept concept_checking_typedef_##type_var##concept
</pre> </pre>
In addition, there are versions of <tt>BOOST_CLASS_REQUIRES</tt> that In addition, there are versions of <tt>BOOST_CLASS_REQUIRE</tt> that
take more arguments, to handle concepts that include interactions take more arguments, to handle concepts that include interactions
between two or more types. <tt>BOOST_CLASS_REQUIRES</tt> was not used between two or more types. <tt>BOOST_CLASS_REQUIRE</tt> was not used
in the implementation of the BCCL concept checks because several in the implementation of the BCCL concept checks because some
compilers do not implement template parameters of function pointer compilers do not implement template parameters of function pointer
type. type.
<!-- We decided not to go with this version since it is easier to misuse <!-- 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 To check the type parameters of class templates, we provide the

View File

@@ -48,6 +48,43 @@ inline void function_requires(type<Concept>* = 0)
#endif #endif
} }
#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
#define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
typedef void (ns::concept <type_var1,type_var2>::* \
func##type_var1##type_var2##concept)(); \
template <func##type_var1##type_var2##concept _Tp1> \
struct concept_checking_##type_var1##type_var2##concept { }; \
typedef concept_checking_##type_var1##type_var2##concept< \
BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
concept_checking_typedef_##type_var1##type_var2##concept
#define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
typedef void (ns::concept <tv1,tv2,tv3>::* \
func##tv1##tv2##tv3##concept)(); \
template <func##tv1##tv2##tv3##concept _Tp1> \
struct concept_checking_##tv1##tv2##tv3##concept { }; \
typedef concept_checking_##tv1##tv2##tv3##concept< \
BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
concept_checking_typedef_##tv1##tv2##tv3##concept
#define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
func##tv1##tv2##tv3##tv4##concept)(); \
template <func##tv1##tv2##tv3##tv4##concept _Tp1> \
struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
// NOTE: The BOOST_CLASS_REQUIRES (with an 'S' at the end) is deprecated.
// The BOOST_CLASS_REQUIRES macros use function pointers as // The BOOST_CLASS_REQUIRES macros use function pointers as
// template parameters, which VC++ does not support. // template parameters, which VC++ does not support.

View File

@@ -44,6 +44,16 @@
<h3><a name="macros">Macros</a></h3> <h3><a name="macros">Macros</a></h3>
<pre>
// Apply concept checks in class definitions.
BOOST_CLASS_REQUIRE(<i>type</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE2(<i>type1</i>, <i>type2</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE3(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>namespace-of-concept</i>, <i>concept</i>);
</pre>
Deprecated macros:
<pre> <pre>
// Apply concept checks in class definitions. // Apply concept checks in class definitions.
BOOST_CLASS_REQUIRES(<i>type</i>, <i>concept</i>); BOOST_CLASS_REQUIRES(<i>type</i>, <i>concept</i>);
@@ -52,7 +62,6 @@
BOOST_CLASS_REQUIRES4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>concept</i>); BOOST_CLASS_REQUIRES4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>concept</i>);
</pre> </pre>
<h3><a name="basic-concepts">Basic Concept Checking Classes</a></h3> <h3><a name="basic-concepts">Basic Concept Checking Classes</a></h3>
<pre> <pre>

View File

@@ -64,12 +64,12 @@ instantiate the concept checking class with the type and then find a
way to get the compiler to compile the <tt>constraints()</tt> function way to get the compiler to compile the <tt>constraints()</tt> function
without actually executing the function. The Boost Concept Checking without actually executing the function. The Boost Concept Checking
Library defines two utilities that make this easy: Library defines two utilities that make this easy:
<tt>function_requires()</tt> and <tt>BOOST_CLASS_REQUIRES</tt>. <tt>function_requires()</tt> and <tt>BOOST_CLASS_REQUIRE</tt>.
<h4><tt>function_requires()</tt></h4> <h4><tt>function_requires()</tt></h4>
The <tt>function_requires()</tt> function can be used in function bodies 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 and the <tt>BOOST_CLASS_REQUIRE</tt> macro can be used inside class
bodies. The <tt>function_requires()</tt> function takes no arguments, bodies. The <tt>function_requires()</tt> function takes no arguments,
but has a template parameter for the concept checking class. This but has a template parameter for the concept checking class. This
means that the instantiated concept checking class must be given as an means that the instantiated concept checking class must be given as an
@@ -97,9 +97,9 @@ explicit template argument, as shown below.
</pre> </pre>
<h4><tt>BOOST_CLASS_REQUIRES</tt></h4> <h4><tt>BOOST_CLASS_REQUIRE</tt></h4>
The <tt>BOOST_CLASS_REQUIRES</tt> macro can be used inside a class The <tt>BOOST_CLASS_REQUIRE</tt> macro can be used inside a class
definition to check whether some type models a concept. definition to check whether some type models a concept.
<pre> <pre>
@@ -107,7 +107,7 @@ definition to check whether some type models a concept.
template &lt;class T&gt; template &lt;class T&gt;
struct generic_library_class struct generic_library_class
{ {
BOOST_CLASS_REQUIRES(T, EqualityComparableConcept); BOOST_CLASS_REQUIRE(T, boost, EqualityComparableConcept);
// ... // ...
}; };
@@ -179,7 +179,7 @@ type for the map.
</pre> </pre>
As an example of using <tt>BOOST_CLASS_REQUIRES</tt> we look at a concept As an example of using <tt>BOOST_CLASS_REQUIRE</tt> we look at a concept
check that could be added to <tt>std::vector</tt>. One requirement 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 that is placed on the element type is that it must be <a
href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>. href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.
@@ -191,7 +191,7 @@ of the definition for <tt>std::vector</tt>.
namespace std { namespace std {
template &lt;class T&gt; template &lt;class T&gt;
struct vector { struct vector {
BOOST_CLASS_REQUIRES(T, AssignableConcept); BOOST_CLASS_REQUIRE(T, boost, AssignableConcept);
... ...
}; };
} }