forked from boostorg/concept_check
*** empty log message ***
[SVN r15038]
This commit is contained in:
9
Jamfile
Normal file
9
Jamfile
Normal 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 ;
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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>
|
||||||
|
@@ -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 <type_var>::* func##type_var##concept)(); \
|
typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
|
||||||
template <func##type_var##concept _Tp1> \
|
template <func##type_var##concept _Tp1> \
|
||||||
struct concept_checking_##type_var##concept { }; \
|
struct concept_checking_##type_var##concept { }; \
|
||||||
typedef concept_checking_##type_var##concept< \
|
typedef concept_checking_##type_var##concept< \
|
||||||
BOOST_FPTR concept <type_var>::constraints> \
|
BOOST_FPTR ns::concept<type_var>::constraints> \
|
||||||
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
|
||||||
|
@@ -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.
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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 <class T>
|
template <class T>
|
||||||
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 <class T>
|
template <class T>
|
||||||
struct vector {
|
struct vector {
|
||||||
BOOST_CLASS_REQUIRES(T, AssignableConcept);
|
BOOST_CLASS_REQUIRE(T, boost, AssignableConcept);
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user