some concept checking changes as per review comments

[SVN r8268]
This commit is contained in:
Jeremy Siek
2000-11-20 18:17:52 +00:00
parent 6e6ebd28d6
commit 86b1612338
15 changed files with 711 additions and 277 deletions

View File

@@ -0,0 +1,29 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRES macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
class class_requires_test
{
BOOST_CLASS_REQUIRES(foo, EqualityComparableConcept);
};
int
main()
{
class_requires_test x;
return 0;
}

View File

@@ -0,0 +1,29 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRES2 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
class class_requires_test
{
BOOST_CLASS_REQUIRES2(foo, foo, Comparable2Concept);
};
int
main()
{
class_requires_test x;
return 0;
}

View File

@@ -0,0 +1,29 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRES3 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
class class_requires_test
{
BOOST_CLASS_REQUIRES3(foo, foo, foo, UnaryFunctionConcept);
};
int
main()
{
class_requires_test x;
return 0;
}

View File

@@ -0,0 +1,27 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRES4 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
class class_requires_test
{
BOOST_CLASS_REQUIRES4(foo, foo, foo, foo, BinaryFunctionConcept);
};
int
main()
{
class_requires_test x;
return 0;
}

View File

@@ -0,0 +1,36 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRES macros of the
Boost Concept Checking Library do not cause errors when
they are not suppose to.
*/
struct foo { bool operator()(int) { return true; } };
struct bar { bool operator()(int, char) { return true; } };
class class_requires_test
{
BOOST_CLASS_REQUIRES(int, EqualityComparableConcept);
typedef int* int_ptr;
typedef const int* const_int_ptr;
BOOST_CLASS_REQUIRES2(int_ptr, const_int_ptr, Comparable2Concept);
BOOST_CLASS_REQUIRES3(foo, bool, int, UnaryFunctionConcept);
BOOST_CLASS_REQUIRES4(bar, bool, int, char, BinaryFunctionConcept);
};
int
main()
{
class_requires_test x;
ignore_unused_variable_warning(x);
return 0;
}

View File

@@ -399,9 +399,9 @@ As an example of how to create a concept checking class, we look
at how to create the corresponding checks for the at how to create the corresponding checks for the
<a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html"> <a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
RandomAccessIterator</a> concept. First, as a convention we name the RandomAccessIterator</a> concept. First, as a convention we name the
concept checking class after the concept, and add the prefix concept checking class after the concept, and add the suffix
``<tt>_concept</tt>''. Note that the <tt>REQUIRE</tt> macro expects ``<tt>_concept</tt>''. Note that the <tt>REQUIRE</tt> macro expects
the prefix to be there. Next we must define a member function named the suffix to be there. Next we must define a member function named
<tt>constraints()</tt> in which we will exercise the valid expressions <tt>constraints()</tt> in which we will exercise the valid expressions
of the concept. The <tt>REQUIRE</tt> macro expects this function's of the concept. The <tt>REQUIRE</tt> macro expects this function's
signature to appear exactly as it is appears below: a <tt>void</tt> signature to appear exactly as it is appears below: a <tt>void</tt>

View File

@@ -0,0 +1,24 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_FUNCTION_REQUIRES macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
int
main()
{
BOOST_FUNCTION_REQUIRES(foo, EqualityComparableConcept);
return 0;
}

View File

@@ -0,0 +1,24 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_FUNCTION_REQUIRES2 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
int
main()
{
BOOST_FUNCTION_REQUIRES2(foo, foo, Comparable2Concept);
return 0;
}

View File

@@ -0,0 +1,24 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_FUNCTION_REQUIRES3 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
int
main()
{
BOOST_FUNCTION_REQUIRES3(foo, foo, foo, UnaryFunctionConcept);
return 0;
}

View File

@@ -0,0 +1,24 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
/*
This file verifies that the BOOST_FUNCTION_REQUIRES4 macro
of the Boost Concept Checking Library catches errors
when it is suppose to.
*/
struct foo { };
int
main()
{
BOOST_FUNCTION_REQUIRES4(foo, foo, foo, foo, BinaryFunctionConcept);
return 0;
}

92
concept_checks_test.cpp Normal file
View File

@@ -0,0 +1,92 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/pending/concept_checks.hpp>
#include <boost/pending/concept_archetypes.hpp>
/*
This file verifies that the BOOST_FUNCTION_REQUIRES macros of the
Boost Concept Checking Library do not cause errors when they are not
suppose to and verifies that the concept archetypes meet the
requirements of their matching concepts.
*/
int
main()
{
using namespace boost;
{
typedef default_constructible_archetype<> foo;
BOOST_FUNCTION_REQUIRES(foo, DefaultConstructibleConcept);
}
{
typedef copy_constructible_archetype<> foo;
BOOST_FUNCTION_REQUIRES(foo, CopyConstructibleConcept);
}
{
typedef assignable_archetype<> foo;
BOOST_FUNCTION_REQUIRES(foo, AssignableConcept);
}
{
typedef copy_constructible_archetype<> foo;
typedef convertible_to_archetype<foo> convertible_to_foo;
BOOST_FUNCTION_REQUIRES2(convertible_to_foo, foo, ConvertibleConcept);
}
{
BOOST_FUNCTION_REQUIRES2(boolean_archetype, bool, ConvertibleConcept);
}
{
typedef unary_function_archetype<int, int> F;
BOOST_FUNCTION_REQUIRES3(F, int, int, UnaryFunctionConcept);
}
{
typedef binary_function_archetype<int, int, int> F;
BOOST_FUNCTION_REQUIRES4(F, int, int, int, BinaryFunctionConcept);
}
{
typedef unary_predicate_archetype<int> F;
BOOST_FUNCTION_REQUIRES2(F, int, UnaryPredicateConcept);
}
{
typedef binary_predicate_archetype<int, int> F;
BOOST_FUNCTION_REQUIRES3(F, int, int, BinaryPredicateConcept);
typedef const_binary_predicate_archetype<int, int> const_F;
BOOST_FUNCTION_REQUIRES3(const_F, int, int, Const_BinaryPredicateConcept);
}
{
typedef trivial_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, TrivialIteratorConcept);
}
{
typedef mutable_trivial_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, Mutable_TrivialIteratorConcept);
}
{
typedef input_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, InputIteratorConcept);
}
{
typedef output_iterator_archetype Iter;
BOOST_FUNCTION_REQUIRES2(Iter, int, OutputIteratorConcept);
}
{
typedef forward_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, ForwardIteratorConcept);
}
{
typedef bidirectional_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, BidirectionalIteratorConcept);
}
{
typedef random_access_iterator_archetype<null_archetype> Iter;
BOOST_FUNCTION_REQUIRES(Iter, RandomAccessIteratorConcept);
}
return 0;
}

View File

@@ -89,6 +89,7 @@ namespace boost {
operator!=(const Left&, const left_equality_comparable_archetype<Left>&) operator!=(const Left&, const left_equality_comparable_archetype<Left>&)
{ return boolean_archetype(dummy_cons); } { return boolean_archetype(dummy_cons); }
template <class Base = null_archetype> template <class Base = null_archetype>
class equality_comparable_archetype : public Base { class equality_comparable_archetype : public Base {
public: public:
@@ -105,6 +106,25 @@ namespace boost {
const equality_comparable_archetype<Base>&) const equality_comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; } { return boolean_archetype(dummy_cons);; }
template <class XX = null_archetype, class YY = null_archetype>
class equality_comparable2_archetype {
public:
friend boolean_archetype operator==(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator!=(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator==(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator!=(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
};
template <class Base = null_archetype> template <class Base = null_archetype>
class less_than_comparable_archetype : public Base { class less_than_comparable_archetype : public Base {
public: public:
@@ -115,22 +135,65 @@ namespace boost {
operator<(const less_than_comparable_archetype<Base>&, operator<(const less_than_comparable_archetype<Base>&,
const less_than_comparable_archetype<Base>&) const less_than_comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; } { return boolean_archetype(dummy_cons);; }
template <class Base = null_archetype>
class comparable_archetype : public Base {
public:
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base> template <class Base>
boolean_archetype boolean_archetype
operator<=(const less_than_comparable_archetype<Base>&, operator<(const comparable_archetype<Base>&,
const less_than_comparable_archetype<Base>&) const comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; } { return boolean_archetype(dummy_cons);; }
template <class Base> template <class Base>
boolean_archetype boolean_archetype
operator>(const less_than_comparable_archetype<Base>&, operator<=(const comparable_archetype<Base>&,
const less_than_comparable_archetype<Base>&) const comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; } { return boolean_archetype(dummy_cons);; }
template <class Base> template <class Base>
boolean_archetype boolean_archetype
operator>=(const less_than_comparable_archetype<Base>&, operator>(const comparable_archetype<Base>&,
const less_than_comparable_archetype<Base>&) const comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; }
template <class Base>
boolean_archetype
operator>=(const comparable_archetype<Base>&,
const comparable_archetype<Base>&)
{ return boolean_archetype(dummy_cons);; } { return boolean_archetype(dummy_cons);; }
template <class XX = null_archetype, class YY = null_archetype>
class comparable2_archetype {
public:
friend boolean_archetype operator<(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator<=(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator>(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator>=(const XX& x, const YY& y) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator<(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator<=(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator>(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
friend boolean_archetype operator>=(const YY& y, const XX& x) {
return boolean_archetype(dummy_cons);
}
};
template <class Base = null_archetype> template <class Base = null_archetype>
class default_constructible_archetype : public Base { class default_constructible_archetype : public Base {
public: public:
@@ -138,6 +201,7 @@ namespace boost {
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { } default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
}; };
template <class Base = null_archetype> template <class Base = null_archetype>
class copy_constructible_archetype : public Base { class copy_constructible_archetype : public Base {
public: public:
@@ -155,7 +219,7 @@ namespace boost {
} }
assignable_archetype(detail::dummy_constructor x) : Base(x) { } assignable_archetype(detail::dummy_constructor x) : Base(x) { }
}; };
//=========================================================================== //===========================================================================
// Function Object Archetype Classes // Function Object Archetype Classes
@@ -245,8 +309,7 @@ namespace boost {
template <class T> template <class T>
struct input_output_proxy { struct input_output_proxy {
input_output_proxy<T>& operator=(const T&) { return *this; } input_output_proxy<T>& operator=(const T&) { return *this; }
operator T() { return t; } operator const T&() { return static_object<T>::get(); }
T t;
}; };
template <class T> template <class T>
class mutable_trivial_iterator_archetype class mutable_trivial_iterator_archetype
@@ -265,7 +328,6 @@ namespace boost {
bool operator==(const self&) const { return true; } bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; } bool operator!=(const self&) const { return true; }
input_output_proxy<T> operator*() { return input_output_proxy<T>(); } input_output_proxy<T> operator*() { return input_output_proxy<T>(); }
T x;
}; };
} // namespace boost } // namespace boost

View File

@@ -5,76 +5,75 @@
// "as is" without express or implied warranty, and with no claim as // "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose. // to its suitability for any purpose.
// //
#ifndef BOOST_GRAPH_DETAIL_CONCEPT_CHECKS_HPP #ifndef BOOST_CONCEPT_CHECKS_HPP
#define BOOST_GRAPH_DETAIL_CONCEPT_CHECKS_HPP #define BOOST_CONCEPT_CHECKS_HPP
#include <iterator> #include <iterator>
#include <utility> #include <utility>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/pending/limits.hpp> #include <boost/pending/limits.hpp>
#if defined(__GNUC__) || defined(__KCC) || defined(__ghs) || defined(__MWERKS__) #if (__GNUC__) || defined(__KCC) || defined(__ghs) || defined(__MWERKS__)
#define BOOST_FPTR & #define BOOST_FPTR &
#else #else
#define BOOST_FPTR #define BOOST_FPTR
#endif #endif
#define REQUIRE(__type_var, __concept) \ #define BOOST_FUNCTION_REQUIRES(type_var, concept) \
do { \ do { \
void (__concept##_concept <__type_var>::*__x)() = \ void (concept<type_var>::*x)() = BOOST_FPTR concept<type_var>::constraints; \
BOOST_FPTR __concept##_concept <__type_var>::constraints; \ x = x; } while (0)
__x = __x; } while (0)
#define REQUIRE2(__type_var1, __type_var2, __concept) \ #define BOOST_FUNCTION_REQUIRES2(type_var1, type_var2, concept) \
do { \ do { \
void (__concept##_concept <__type_var1, __type_var2>::*__x)() = \ void (concept<type_var1, type_var2>::*x)() = \
BOOST_FPTR __concept##_concept <__type_var1, __type_var2>::constraints; \ BOOST_FPTR concept<type_var1, type_var2>::constraints; \
__x = __x; } while (0) x = x; } while (0)
#define REQUIRE3(__type_var1, __type_var2, __type_var3,__concept) \ #define BOOST_FUNCTION_REQUIRES3(type_var1, type_var2, type_var3,concept) \
do { \ do { \
void (__concept##_concept <__type_var1, __type_var2, __type_var3>::*__x)() = \ void (concept <type_var1, type_var2, type_var3>::*x)() = \
BOOST_FPTR __concept##_concept <__type_var1, __type_var2, __type_var3>::constraints; \ BOOST_FPTR concept <type_var1, type_var2, type_var3>::constraints; \
__x = __x; } while (0) x = x; } while (0)
#define REQUIRE4(__type_var1, __type_var2, __type_var3,__type_var4,__concept) \ #define BOOST_FUNCTION_REQUIRES4(type_var1, type_var2, type_var3,type_var4,concept) \
do { \ do { \
void (__concept##_concept <__type_var1,__type_var2,__type_var3,__type_var4>::*__x)() = \ void (concept <type_var1,type_var2,type_var3,type_var4>::*x)() = \
BOOST_FPTR __concept##_concept <__type_var1, __type_var2, __type_var3, __type_var4>::constraints;\ BOOST_FPTR concept <type_var1, type_var2, type_var3, type_var4>::constraints;\
__x = __x; } while (0) x = x; } while (0)
#define CLASS_REQUIRES(__tv, __concept) \ #define BOOST_CLASS_REQUIRES(type_var, concept) \
typedef void (__concept##_concept <__tv>::* __func##__tv##__concept)(); \ typedef void (concept <type_var>::* __func##type_var##concept)(); \
template <__func##__tv##__concept _Tp1> \ template <__func##type_var##concept _Tp1> \
struct __dummy_struct_##__tv##__concept { }; \ struct __dummy_struct_##type_var##concept { }; \
typedef __dummy_struct_##__tv##__concept< \ typedef __dummy_struct_##type_var##concept< \
BOOST_FPTR __concept##_concept <__tv>::constraints> \ BOOST_FPTR concept <type_var>::constraints> \
__dummy_typedef_##__tv##__concept __dummy_typedef_##type_var##concept
#define CLASS_REQUIRES2(__tv1, __tv2, __concept) \ #define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
typedef void (__concept##_concept <__tv1,__tv2>::* __func##__tv1##__tv2##__concept)(); \ typedef void (concept <type_var1,type_var2>::* __func##type_var1##type_var2##concept)(); \
template <__func##__tv1##__tv2##__concept _Tp1> \ template <__func##type_var1##type_var2##concept _Tp1> \
struct __dummy_struct_##__tv1##__tv2##__concept { }; \ struct __dummy_struct_##type_var1##type_var2##concept { }; \
typedef __dummy_struct_##__tv1##__tv2##__concept< \ typedef __dummy_struct_##type_var1##type_var2##concept< \
BOOST_FPTR __concept##_concept <__tv1,__tv2>::constraints> \ BOOST_FPTR concept <type_var1,type_var2>::constraints> \
__dummy_typedef_##__tv1##__tv2##__concept __dummy_typedef_##type_var1##type_var2##concept
#define CLASS_REQUIRES3(__tv1, __tv2, __tv3, __concept) \ #define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
typedef void (__concept##_concept <__tv1,__tv2,__tv3>::* __func##__tv1##__tv2##__tv3##__concept)(); \ typedef void (concept <type_var1,type_var2,type_var3>::* __func##type_var1##type_var2##type_var3##concept)(); \
template <__func##__tv1##__tv2##__tv3##__concept _Tp1> \ template <__func##type_var1##type_var2##type_var3##concept _Tp1> \
struct __dummy_struct_##__tv1##__tv2##__tv3##__concept { }; \ struct __dummy_struct_##type_var1##type_var2##type_var3##concept { }; \
typedef __dummy_struct_##__tv1##__tv2##__tv3##__concept< \ typedef __dummy_struct_##type_var1##type_var2##type_var3##concept< \
BOOST_FPTR __concept##_concept <__tv1,__tv2,__tv3>::constraints> \ BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints> \
__dummy_typedef_##__tv1##__tv2##__tv3##__concept __dummy_typedef_##type_var1##type_var2##type_var3##concept
#define CLASS_REQUIRES4(__tv1, __tv2, __tv3, __tv4, __concept) \ #define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
typedef void (__concept##_concept <__tv1,__tv2,__tv3,__tv4>::* __func##__tv1##__tv2##__tv3##__tv4##__concept)(); \ typedef void (concept <type_var1,type_var2,type_var3,type_var4>::* __func##type_var1##type_var2##type_var3##type_var4##concept)(); \
template <__func##__tv1##__tv2##__tv3##__tv4##__concept _Tp1> \ template <__func##type_var1##type_var2##type_var3##type_var4##concept _Tp1> \
struct __dummy_struct_##__tv1##__tv2##__tv3##__tv4##__concept { }; \ struct __dummy_struct_##type_var1##type_var2##type_var3##type_var4##concept { }; \
typedef __dummy_struct_##__tv1##__tv2##__tv3##__tv4##__concept< \ typedef __dummy_struct_##type_var1##type_var2##type_var3##type_var4##concept< \
BOOST_FPTR __concept##_concept <__tv1,__tv2,__tv3,__tv4>::constraints> \ BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints> \
__dummy_typedef_##__tv1##__tv2##__tv3##__tv4##__concept __dummy_typedef_##type_var1##type_var2##type_var3##type_var4##concept
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@@ -88,16 +87,16 @@ template <class T, class U>
struct require_same_type { typedef T type; }; struct require_same_type { typedef T type; };
#endif #endif
#define REQUIRE_SAME_TYPE(X,Y) \ #define BOOST_FUNCTION_REQUIRES_SAME_TYPE(X,Y) \
typedef typename require_same_type<X,Y>::type X##_same_##Y typedef typename require_same_type<X,Y>::type X##_same_##Y
#define CLASS_REQUIRES_SAME_TYPE(X,Y) \ #define BOOST_CLASS_REQUIRES_SAME_TYPE(X,Y) \
typedef typename require_same_type<X,Y>::type X##_same_##Y typedef typename require_same_type<X,Y>::type X##_same_##Y
template <class T> void ignore_unused_variable_warning(const T&) { } template <class T> void ignore_unused_variable_warning(const T&) { }
template <class T> template <class T>
struct Integer_concept { struct IntegerConcept {
void constraints() { void constraints() {
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
error__type_must_be_an_integer_type(); error__type_must_be_an_integer_type();
@@ -105,17 +104,17 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
} }
}; };
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <> struct Integer_concept<short> { void constraints() {} }; template <> struct IntegerConcept<short> { void constraints() {} };
template <> struct Integer_concept<unsigned short> { void constraints() {} }; template <> struct IntegerConcept<unsigned short> { void constraints() {} };
template <> struct Integer_concept<int> { void constraints() {} }; template <> struct IntegerConcept<int> { void constraints() {} };
template <> struct Integer_concept<unsigned int> { void constraints() {} }; template <> struct IntegerConcept<unsigned int> { void constraints() {} };
template <> struct Integer_concept<long> { void constraints() {} }; template <> struct IntegerConcept<long> { void constraints() {} };
template <> struct Integer_concept<unsigned long> { void constraints() {} }; template <> struct IntegerConcept<unsigned long> { void constraints() {} };
// etc. // etc.
#endif #endif
template <class T> template <class T>
struct SignedInteger_concept { struct SignedIntegerConcept {
void constraints() { void constraints() {
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
error__type_must_be_a_signed_integer_type(); error__type_must_be_a_signed_integer_type();
@@ -123,9 +122,9 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
} }
}; };
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <> struct SignedInteger_concept<short> { void constraints() {} }; template <> struct SignedIntegerConcept<short> { void constraints() {} };
template <> struct SignedInteger_concept<int> { void constraints() {} }; template <> struct SignedIntegerConcept<int> { void constraints() {} };
template <> struct SignedInteger_concept<long> { void constraints() {} }; template <> struct SignedIntegerConcept<long> { void constraints() {} };
// etc. // etc.
#endif #endif
@@ -133,7 +132,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
// Basic Concepts // Basic Concepts
template <class X, class Y> template <class X, class Y>
struct Convertible_concept struct ConvertibleConcept
{ {
void constraints() { void constraints() {
Y y = x; Y y = x;
@@ -142,11 +141,8 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
X x; X x;
}; };
// Issue, the SGI STL version of Assignable is
// different from the C++ standard definition of Assignable.
// This follows the C++ standard version.
template <class TT> template <class TT>
struct Assignable_concept struct AssignableConcept
{ {
void constraints() { void constraints() {
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
@@ -163,7 +159,24 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct DefaultConstructible_concept struct AssignableSGIConcept
{
void constraints() {
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
a = a; // require assignment operator
#endif
const_constraints(a);
}
void const_constraints(const TT& b) {
#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
a = b; // const required for argument to assignment
#endif
}
TT a;
};
template <class TT>
struct DefaultConstructibleConcept
{ {
void constraints() { void constraints() {
TT a; // require default constructor TT a; // require default constructor
@@ -172,16 +185,19 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class T> template <class T>
struct CopyConstructible_concept struct CopyConstructibleConcept
{ {
void constraints() { void constraints() {
T a(b); // require copy constructor T a(b); // require copy constructor
T* ptr = &a; // require address of operator T* ptr = &a; // require address of operator
const_constraints(a); const_constraints(a);
ignore_unused_variable_warning(ptr);
} }
void const_constraints(const T& a) { void const_constraints(const T& a) {
T c(a); // require const copy constructor T c(a); // require const copy constructor
const T* ptr = &a; // require const address of operator const T* ptr = &a; // require const address of operator
ignore_unused_variable_warning(c);
ignore_unused_variable_warning(ptr);
} }
T b; T b;
}; };
@@ -202,7 +218,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
} }
template <class TT> template <class TT>
struct EqualityComparable_concept struct EqualityComparableConcept
{ {
void constraints() { void constraints() {
require_boolean_expr(a == b); require_boolean_expr(a == b);
@@ -213,18 +229,34 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class XX, class YY> template <class XX, class YY>
struct LeftEqualityComparable_concept struct EqualityComparable2Concept
{ {
void constraints() { void constraints() {
require_boolean_expr(a == b);
require_boolean_expr(b == a); require_boolean_expr(b == a);
require_boolean_expr(a != b);
require_boolean_expr(b != a); require_boolean_expr(b != a);
} }
XX a; XX a;
YY b; YY b;
}; };
// Use LessThanOpConcept (see below) instead of
// LessThanComparableConcept when you want to express comparison
// between two different types.
template <class TT> template <class TT>
struct LessThanComparable_concept struct LessThanComparableConcept
{
void constraints() {
require_boolean_expr(a < b);
}
bool boolean;
TT a, b;
};
// This is equivalent to SGI STL's LessThanComparable.
template <class TT>
struct ComparableConcept
{ {
void constraints() { void constraints() {
require_boolean_expr(a < b); require_boolean_expr(a < b);
@@ -236,16 +268,34 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
TT a, b; TT a, b;
}; };
template <class XX, class YY>
struct Comparable2Concept
{
void constraints() {
require_boolean_expr(a < b);
require_boolean_expr(b < a);
require_boolean_expr(a > b);
require_boolean_expr(b > a);
require_boolean_expr(a <= b);
require_boolean_expr(b <= a);
require_boolean_expr(a >= b);
require_boolean_expr(b >= a);
}
bool boolean;
XX a;
YY b;
};
//=========================================================================== //===========================================================================
// Iterator Concepts // Iterator Concepts
template <class TT> template <class TT>
struct TrivialIterator_concept struct TrivialIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, Assignable); BOOST_FUNCTION_REQUIRES(TT, AssignableConcept);
REQUIRE(TT, DefaultConstructible); BOOST_FUNCTION_REQUIRES(TT, DefaultConstructibleConcept);
REQUIRE(TT, EqualityComparable); BOOST_FUNCTION_REQUIRES(TT, EqualityComparableConcept);
#ifndef BOOST_NO_STD_ITERATOR_TRAITS #ifndef BOOST_NO_STD_ITERATOR_TRAITS
typedef typename std::iterator_traits<TT>::value_type V; typedef typename std::iterator_traits<TT>::value_type V;
#endif #endif
@@ -255,29 +305,29 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct Mutable_TrivialIterator_concept struct Mutable_TrivialIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, TrivialIterator); BOOST_FUNCTION_REQUIRES(TT, TrivialIteratorConcept);
*i = *j; // require dereference and assignment *i = *j; // require dereference and assignment
} }
TT i, j; TT i, j;
}; };
template <class TT> template <class TT>
struct InputIterator_concept struct InputIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, TrivialIterator); BOOST_FUNCTION_REQUIRES(TT, TrivialIteratorConcept);
// require iterator_traits typedef's // require iterator_traits typedef's
#ifndef BOOST_NO_STD_ITERATOR_TRAITS #ifndef BOOST_NO_STD_ITERATOR_TRAITS
typedef typename std::iterator_traits<TT>::difference_type D; typedef typename std::iterator_traits<TT>::difference_type D;
REQUIRE(D, SignedInteger); BOOST_FUNCTION_REQUIRES(D, SignedIntegerConcept);
typedef typename std::iterator_traits<TT>::reference R; typedef typename std::iterator_traits<TT>::reference R;
typedef typename std::iterator_traits<TT>::pointer P; typedef typename std::iterator_traits<TT>::pointer P;
typedef typename std::iterator_traits<TT>::iterator_category C; typedef typename std::iterator_traits<TT>::iterator_category C;
REQUIRE2(typename std::iterator_traits<TT>::iterator_category, BOOST_FUNCTION_REQUIRES2(typename std::iterator_traits<TT>::iterator_category,
std::input_iterator_tag, Convertible); std::input_iterator_tag, ConvertibleConcept);
#endif #endif
++i; // require preincrement operator ++i; // require preincrement operator
i++; // require postincrement operator i++; // require postincrement operator
@@ -286,10 +336,10 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT, class ValueT> template <class TT, class ValueT>
struct OutputIterator_concept struct OutputIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, Assignable); BOOST_FUNCTION_REQUIRES(TT, AssignableConcept);
++i; // require preincrement operator ++i; // require preincrement operator
i++; // require postincrement operator i++; // require postincrement operator
*i++ = t; // require postincrement and assignment *i++ = t; // require postincrement and assignment
@@ -299,13 +349,13 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct ForwardIterator_concept struct ForwardIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, InputIterator); BOOST_FUNCTION_REQUIRES(TT, InputIteratorConcept);
#ifndef BOOST_NO_STD_ITERATOR_TRAITS #ifndef BOOST_NO_STD_ITERATOR_TRAITS
REQUIRE2(typename std::iterator_traits<TT>::iterator_category, BOOST_FUNCTION_REQUIRES2(typename std::iterator_traits<TT>::iterator_category,
std::forward_iterator_tag, Convertible); std::forward_iterator_tag, ConvertibleConcept);
typedef typename std::iterator_traits<TT>::reference reference; typedef typename std::iterator_traits<TT>::reference reference;
reference r = *i; reference r = *i;
ignore_unused_variable_warning(r); ignore_unused_variable_warning(r);
@@ -315,23 +365,23 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct Mutable_ForwardIterator_concept struct Mutable_ForwardIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, ForwardIterator); BOOST_FUNCTION_REQUIRES(TT, ForwardIteratorConcept);
*i++ = *i; // require postincrement and assignment *i++ = *i; // require postincrement and assignment
} }
TT i; TT i;
}; };
template <class TT> template <class TT>
struct BidirectionalIterator_concept struct BidirectionalIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, ForwardIterator); BOOST_FUNCTION_REQUIRES(TT, ForwardIteratorConcept);
#ifndef BOOST_NO_STD_ITERATOR_TRAITS #ifndef BOOST_NO_STD_ITERATOR_TRAITS
REQUIRE2(typename std::iterator_traits<TT>::iterator_category, BOOST_FUNCTION_REQUIRES2(typename std::iterator_traits<TT>::iterator_category,
std::bidirectional_iterator_tag, Convertible); std::bidirectional_iterator_tag, ConvertibleConcept);
#endif #endif
--i; // require predecrement operator --i; // require predecrement operator
i--; // require postdecrement operator i--; // require postdecrement operator
@@ -340,11 +390,11 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct Mutable_BidirectionalIterator_concept struct Mutable_BidirectionalIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, BidirectionalIterator); BOOST_FUNCTION_REQUIRES(TT, BidirectionalIteratorConcept);
REQUIRE(TT, Mutable_ForwardIterator); BOOST_FUNCTION_REQUIRES(TT, Mutable_ForwardIteratorConcept);
*i-- = *i; // require postdecrement and assignment *i-- = *i; // require postdecrement and assignment
} }
TT i; TT i;
@@ -352,14 +402,14 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
template <class TT> template <class TT>
struct RandomAccessIterator_concept struct RandomAccessIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, BidirectionalIterator); BOOST_FUNCTION_REQUIRES(TT, BidirectionalIteratorConcept);
REQUIRE(TT, LessThanComparable); BOOST_FUNCTION_REQUIRES(TT, ComparableConcept);
#ifndef BOOST_NO_STD_ITERATOR_TRAITS #ifndef BOOST_NO_STD_ITERATOR_TRAITS
REQUIRE2(typename std::iterator_traits<TT>::iterator_category, BOOST_FUNCTION_REQUIRES2(typename std::iterator_traits<TT>::iterator_category,
std::random_access_iterator_tag, Convertible); std::random_access_iterator_tag, ConvertibleConcept);
typedef typename std::iterator_traits<TT>::reference R; typedef typename std::iterator_traits<TT>::reference R;
#endif #endif
@@ -380,11 +430,11 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class TT> template <class TT>
struct Mutable_RandomAccessIterator_concept struct Mutable_RandomAccessIteratorConcept
{ {
void constraints() { void constraints() {
REQUIRE(TT, RandomAccessIterator); BOOST_FUNCTION_REQUIRES(TT, RandomAccessIteratorConcept);
REQUIRE(TT, Mutable_BidirectionalIterator); BOOST_FUNCTION_REQUIRES(TT, Mutable_BidirectionalIteratorConcept);
i[n] = *i; // require element access and assignment i[n] = *i; // require element access and assignment
} }
TT i; TT i;
@@ -399,7 +449,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
// Function Object Concepts // Function Object Concepts
template <class _Func, class _Ret> template <class _Func, class _Ret>
struct Generator_concept struct GeneratorConcept
{ {
void constraints() { void constraints() {
__r = __f(); // require operator() member function __r = __f(); // require operator() member function
@@ -411,7 +461,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class _Func> template <class _Func>
struct Generator_concept<_Func,void> struct GeneratorConcept<_Func,void>
{ {
void constraints() { void constraints() {
__f(); // require operator() member function __f(); // require operator() member function
@@ -421,7 +471,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#endif #endif
template <class _Func, class _Ret, class _Arg> template <class _Func, class _Ret, class _Arg>
struct UnaryFunction_concept struct UnaryFunctionConcept
{ {
void constraints() { void constraints() {
__r = __f(__arg); // require operator() __r = __f(__arg); // require operator()
@@ -433,7 +483,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class _Func, class _Arg> template <class _Func, class _Arg>
struct UnaryFunction_concept<_Func,void,_Arg> { struct UnaryFunctionConcept<_Func,void,_Arg> {
void constraints() { void constraints() {
__f(__arg); // require operator() __f(__arg); // require operator()
} }
@@ -442,7 +492,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#endif #endif
template <class _Func, class _Ret, class _First, class _Second> template <class _Func, class _Ret, class _First, class _Second>
struct BinaryFunction_concept struct BinaryFunctionConcept
{ {
void constraints() { void constraints() {
__r = __f(__first, __second); // require operator() __r = __f(__first, __second); // require operator()
@@ -455,7 +505,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class _Func, class _First, class _Second> template <class _Func, class _First, class _Second>
struct BinaryFunction_concept<_Func,void,_First,_Second> struct BinaryFunctionConcept<_Func,void,_First,_Second>
{ {
void constraints() { void constraints() {
__f(__first, __second); // require operator() __f(__first, __second); // require operator()
@@ -467,7 +517,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
#endif #endif
template <class Func, class Arg> template <class Func, class Arg>
struct UnaryPredicate_concept struct UnaryPredicateConcept
{ {
void constraints() { void constraints() {
require_boolean_expr(f(arg)); // require operator() returning bool require_boolean_expr(f(arg)); // require operator() returning bool
@@ -477,7 +527,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class Func, class First, class Second> template <class Func, class First, class Second>
struct BinaryPredicate_concept struct BinaryPredicateConcept
{ {
void constraints() { void constraints() {
require_boolean_expr(f(a, b)); // require operator() returning bool require_boolean_expr(f(a, b)); // require operator() returning bool
@@ -489,12 +539,12 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
// use this when functor is used inside a container class like std::set // use this when functor is used inside a container class like std::set
template <class Func, class First, class Second> template <class Func, class First, class Second>
struct Const_BinaryPredicate_concept { struct Const_BinaryPredicateConcept {
void constraints() { void constraints() {
const_constraints(f); const_constraints(f);
} }
void const_constraints(const Func& fun) { void const_constraints(const Func& fun) {
REQUIRE3(Func, First, Second, BinaryPredicate); BOOST_FUNCTION_REQUIRES3(Func, First, Second, BinaryPredicateConcept);
// operator() must be a const member function // operator() must be a const member function
require_boolean_expr(fun(a, b)); require_boolean_expr(fun(a, b));
} }
@@ -503,34 +553,46 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
Second b; Second b;
}; };
#define __STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
template <class _Ret, class _First, class _Second> \ template <class First, class Second> \
struct _NAME##_concept { \ struct NAME { \
void constraints() { (void)_constraints(); } \ void constraints() { (void)constraints_(); } \
_Ret _constraints() { \ bool constraints_() { \
return __a _OP __b; \ return a OP b; \
} \ } \
_First __a; \ First a; \
_Second __b; \ Second b; \
} }
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(==, _OP_EQUAL); #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(!=, _OP_NOT_EQUAL); template <class Ret, class First, class Second> \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(<, _OP_LESS_THAN); struct NAME { \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(<=, _OP_LESS_EQUAL); void constraints() { (void)constraints_(); } \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(>, _OP_GREATER_THAN); Ret constraints_() { \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(>=, _OP_GREATER_EQUAL); Ret x = a OP b; \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _OP_PLUS); } \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _OP_TIMES); First a; \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _OP_DIVIDE); Second b; \
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _OP_SUBTRACT); }
__STL_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _OP_MOD);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
//=========================================================================== //===========================================================================
// Container Concepts // Container Concepts
template <class Container> template <class Container>
struct Container_concept struct ContainerConcept
{ {
typedef typename Container::value_type value_type; typedef typename Container::value_type value_type;
typedef typename Container::difference_type difference_type; typedef typename Container::difference_type difference_type;
@@ -540,8 +602,8 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
typedef typename Container::const_iterator const_iterator; typedef typename Container::const_iterator const_iterator;
void constraints() { void constraints() {
REQUIRE(const_iterator, InputIterator); BOOST_FUNCTION_REQUIRES(const_iterator, InputIteratorConcept);
REQUIRE(Container, Assignable); BOOST_FUNCTION_REQUIRES(Container, AssignableConcept);
const Container c; const Container c;
i = c.begin(); i = c.begin();
i = c.end(); i = c.end();
@@ -555,7 +617,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class Container> template <class Container>
struct Mutable_Container_concept struct Mutable_ContainerConcept
{ {
typedef typename Container::value_type value_type; typedef typename Container::value_type value_type;
typedef typename Container::reference reference; typedef typename Container::reference reference;
@@ -563,9 +625,9 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
typedef typename Container::pointer pointer; typedef typename Container::pointer pointer;
void constraints() { void constraints() {
REQUIRE(Container, Container); BOOST_FUNCTION_REQUIRES(Container, ContainerConcept);
REQUIRE(value_type, Assignable); BOOST_FUNCTION_REQUIRES(value_type, AssignableConcept);
REQUIRE(iterator, InputIterator); BOOST_FUNCTION_REQUIRES(iterator, InputIteratorConcept);
i = c.begin(); i = c.begin();
i = c.end(); i = c.end();
@@ -576,37 +638,37 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class ForwardContainer> template <class ForwardContainer>
struct ForwardContainer_concept struct ForwardContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(ForwardContainer, Container); BOOST_FUNCTION_REQUIRES(ForwardContainer, ContainerConcept);
typedef typename ForwardContainer::const_iterator const_iterator; typedef typename ForwardContainer::const_iterator const_iterator;
REQUIRE(const_iterator, ForwardIterator); BOOST_FUNCTION_REQUIRES(const_iterator, ForwardIteratorConcept);
} }
}; };
template <class ForwardContainer> template <class ForwardContainer>
struct Mutable_ForwardContainer_concept struct Mutable_ForwardContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(ForwardContainer, ForwardContainer); BOOST_FUNCTION_REQUIRES(ForwardContainer, ForwardContainerConcept);
REQUIRE(ForwardContainer, Mutable_Container); BOOST_FUNCTION_REQUIRES(ForwardContainer, Mutable_ContainerConcept);
typedef typename ForwardContainer::iterator iterator; typedef typename ForwardContainer::iterator iterator;
REQUIRE(iterator, Mutable_ForwardIterator); BOOST_FUNCTION_REQUIRES(iterator, Mutable_ForwardIteratorConcept);
} }
}; };
template <class ReversibleContainer> template <class ReversibleContainer>
struct ReversibleContainer_concept struct ReversibleContainerConcept
{ {
typedef typename ReversibleContainer::const_iterator const_iterator; typedef typename ReversibleContainer::const_iterator const_iterator;
typedef typename ReversibleContainer::const_reverse_iterator typedef typename ReversibleContainer::const_reverse_iterator
const_reverse_iterator; const_reverse_iterator;
void constraints() { void constraints() {
REQUIRE(ReversibleContainer, ForwardContainer); BOOST_FUNCTION_REQUIRES(ReversibleContainer, ForwardContainerConcept);
REQUIRE(const_iterator, BidirectionalIterator); BOOST_FUNCTION_REQUIRES(const_iterator, BidirectionalIteratorConcept);
REQUIRE(const_reverse_iterator, BidirectionalIterator); BOOST_FUNCTION_REQUIRES(const_reverse_iterator, BidirectionalIteratorConcept);
const ReversibleContainer c; const ReversibleContainer c;
const_reverse_iterator i = c.rbegin(); const_reverse_iterator i = c.rbegin();
@@ -615,16 +677,16 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class ReversibleContainer> template <class ReversibleContainer>
struct Mutable_ReversibleContainer_concept struct Mutable_ReversibleContainerConcept
{ {
typedef typename ReversibleContainer::iterator iterator; typedef typename ReversibleContainer::iterator iterator;
typedef typename ReversibleContainer::reverse_iterator reverse_iterator; typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
void constraints() { void constraints() {
REQUIRE(ReversibleContainer, ReversibleContainer); BOOST_FUNCTION_REQUIRES(ReversibleContainer, ReversibleContainerConcept);
REQUIRE(ReversibleContainer, Mutable_ForwardContainer); BOOST_FUNCTION_REQUIRES(ReversibleContainer, Mutable_ForwardContainerConcept);
REQUIRE(iterator, Mutable_BidirectionalIterator); BOOST_FUNCTION_REQUIRES(iterator, Mutable_BidirectionalIteratorConcept);
REQUIRE(reverse_iterator, Mutable_BidirectionalIterator); BOOST_FUNCTION_REQUIRES(reverse_iterator, Mutable_BidirectionalIteratorConcept);
reverse_iterator i = c.rbegin(); reverse_iterator i = c.rbegin();
i = c.rend(); i = c.rend();
@@ -633,7 +695,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class RandomAccessContainer> template <class RandomAccessContainer>
struct RandomAccessContainer_concept struct RandomAccessContainerConcept
{ {
typedef typename RandomAccessContainer::size_type size_type; typedef typename RandomAccessContainer::size_type size_type;
typedef typename RandomAccessContainer::const_reference const_reference; typedef typename RandomAccessContainer::const_reference const_reference;
@@ -642,9 +704,9 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
const_reverse_iterator; const_reverse_iterator;
void constraints() { void constraints() {
REQUIRE(RandomAccessContainer, ReversibleContainer); BOOST_FUNCTION_REQUIRES(RandomAccessContainer, ReversibleContainerConcept);
REQUIRE(const_iterator, RandomAccessIterator); BOOST_FUNCTION_REQUIRES(const_iterator, RandomAccessIteratorConcept);
REQUIRE(const_reverse_iterator, RandomAccessIterator); BOOST_FUNCTION_REQUIRES(const_reverse_iterator, RandomAccessIteratorConcept);
const RandomAccessContainer c; const RandomAccessContainer c;
const_reference r = c[n]; const_reference r = c[n];
@@ -654,7 +716,7 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class RandomAccessContainer> template <class RandomAccessContainer>
struct Mutable_RandomAccessContainer_concept struct Mutable_RandomAccessContainerConcept
{ {
typedef typename RandomAccessContainer::size_type size_type; typedef typename RandomAccessContainer::size_type size_type;
typedef typename RandomAccessContainer::reference reference; typedef typename RandomAccessContainer::reference reference;
@@ -662,10 +724,10 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
typedef typename RandomAccessContainer::reverse_iterator reverse_iterator; typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
void constraints() { void constraints() {
REQUIRE(RandomAccessContainer, RandomAccessContainer); BOOST_FUNCTION_REQUIRES(RandomAccessContainer, RandomAccessContainerConcept);
REQUIRE(RandomAccessContainer, Mutable_ReversibleContainer); BOOST_FUNCTION_REQUIRES(RandomAccessContainer, Mutable_ReversibleContainerConcept);
REQUIRE(iterator, Mutable_RandomAccessIterator); BOOST_FUNCTION_REQUIRES(iterator, Mutable_RandomAccessIteratorConcept);
REQUIRE(reverse_iterator, Mutable_RandomAccessIterator); BOOST_FUNCTION_REQUIRES(reverse_iterator, Mutable_RandomAccessIteratorConcept);
reference r = c[i]; reference r = c[i];
ignore_unused_variable_warning(r); ignore_unused_variable_warning(r);
@@ -676,18 +738,18 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
// A Sequence is inherently mutable // A Sequence is inherently mutable
template <class Sequence> template <class Sequence>
struct Sequence_concept struct SequenceConcept
{ {
// Matt put's DefaultConstructible here, the C++ standard // Matt Austern's book puts DefaultConstructible here, the C++
// places it in Container // standard places it in Container
// CLASS_REQUIRES(Sequence, DefaultConstructible); // BOOST_CLASS_REQUIRES(Sequence, DefaultConstructible);
typedef typename Sequence::reference reference; typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference; typedef typename Sequence::const_reference const_reference;
void constraints() { void constraints() {
REQUIRE(Sequence, Mutable_ForwardContainer); BOOST_FUNCTION_REQUIRES(Sequence, Mutable_ForwardContainerConcept);
REQUIRE(Sequence, DefaultConstructible); BOOST_FUNCTION_REQUIRES(Sequence, DefaultConstructibleConcept);
Sequence Sequence
c(n), c(n),
@@ -720,10 +782,10 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class FrontInsertionSequence> template <class FrontInsertionSequence>
struct FrontInsertionSequence_concept struct FrontInsertionSequenceConcept
{ {
void constraints() { void constraints() {
REQUIRE(FrontInsertionSequence, Sequence); BOOST_FUNCTION_REQUIRES(FrontInsertionSequence, SequenceConcept);
c.push_front(t); c.push_front(t);
c.pop_front(); c.pop_front();
@@ -733,13 +795,13 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class BackInsertionSequence> template <class BackInsertionSequence>
struct BackInsertionSequence_concept struct BackInsertionSequenceConcept
{ {
typedef typename BackInsertionSequence::reference reference; typedef typename BackInsertionSequence::reference reference;
typedef typename BackInsertionSequence::const_reference const_reference; typedef typename BackInsertionSequence::const_reference const_reference;
void constraints() { void constraints() {
REQUIRE(BackInsertionSequence, Sequence); BOOST_FUNCTION_REQUIRES(BackInsertionSequence, SequenceConcept);
c.push_back(t); c.push_back(t);
c.pop_back(); c.pop_back();
@@ -755,11 +817,11 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class AssociativeContainer> template <class AssociativeContainer>
struct AssociativeContainer_concept struct AssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(AssociativeContainer, ForwardContainer); BOOST_FUNCTION_REQUIRES(AssociativeContainer, ForwardContainerConcept);
REQUIRE(AssociativeContainer, DefaultConstructible); BOOST_FUNCTION_REQUIRES(AssociativeContainer, DefaultConstructibleConcept);
i = c.find(k); i = c.find(k);
r = c.equal_range(k); r = c.equal_range(k);
@@ -786,10 +848,10 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class UniqueAssociativeContainer> template <class UniqueAssociativeContainer>
struct UniqueAssociativeContainer_concept struct UniqueAssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(UniqueAssociativeContainer, AssociativeContainer); BOOST_FUNCTION_REQUIRES(UniqueAssociativeContainer, AssociativeContainerConcept);
UniqueAssociativeContainer c(first, last); UniqueAssociativeContainer c(first, last);
@@ -804,10 +866,10 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class MultipleAssociativeContainer> template <class MultipleAssociativeContainer>
struct MultipleAssociativeContainer_concept struct MultipleAssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(MultipleAssociativeContainer, AssociativeContainer); BOOST_FUNCTION_REQUIRES(MultipleAssociativeContainer, AssociativeContainerConcept);
MultipleAssociativeContainer c(first, last); MultipleAssociativeContainer c(first, last);
@@ -823,35 +885,35 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
}; };
template <class SimpleAssociativeContainer> template <class SimpleAssociativeContainer>
struct SimpleAssociativeContainer_concept struct SimpleAssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(SimpleAssociativeContainer, AssociativeContainer); BOOST_FUNCTION_REQUIRES(SimpleAssociativeContainer, AssociativeContainerConcept);
typedef typename SimpleAssociativeContainer::key_type key_type; typedef typename SimpleAssociativeContainer::key_type key_type;
typedef typename SimpleAssociativeContainer::value_type value_type; typedef typename SimpleAssociativeContainer::value_type value_type;
REQUIRE_SAME_TYPE(key_type, value_type); BOOST_FUNCTION_REQUIRES_SAME_TYPE(key_type, value_type);
} }
}; };
template <class SimpleAssociativeContainer> template <class SimpleAssociativeContainer>
struct PairAssociativeContainer_concept struct PairAssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(SimpleAssociativeContainer, AssociativeContainer); BOOST_FUNCTION_REQUIRES(SimpleAssociativeContainer, AssociativeContainerConcept);
typedef typename SimpleAssociativeContainer::key_type key_type; typedef typename SimpleAssociativeContainer::key_type key_type;
typedef typename SimpleAssociativeContainer::value_type value_type; typedef typename SimpleAssociativeContainer::value_type value_type;
typedef typename SimpleAssociativeContainer::mapped_type mapped_type; typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
typedef std::pair<const key_type, mapped_type> required_value_type; typedef std::pair<const key_type, mapped_type> required_value_type;
REQUIRE_SAME_TYPE(value_type, required_value_type); BOOST_FUNCTION_REQUIRES_SAME_TYPE(value_type, required_value_type);
} }
}; };
template <class SortedAssociativeContainer> template <class SortedAssociativeContainer>
struct SortedAssociativeContainer_concept struct SortedAssociativeContainerConcept
{ {
void constraints() { void constraints() {
REQUIRE(SortedAssociativeContainer, AssociativeContainer); BOOST_FUNCTION_REQUIRES(SortedAssociativeContainer, AssociativeContainerConcept);
REQUIRE(SortedAssociativeContainer, ReversibleContainer); BOOST_FUNCTION_REQUIRES(SortedAssociativeContainer, ReversibleContainerConcept);
SortedAssociativeContainer SortedAssociativeContainer
c(kc), c(kc),
@@ -891,5 +953,5 @@ template <class T> void ignore_unused_variable_warning(const T&) { }
// HashedAssociativeContainer // HashedAssociativeContainer
#endif /* BOOST_GRAPH_DETAIL_CONCEPT_CHECKS_H */ #endif // BOOST_CONCEPT_CHECKS_HPP

View File

@@ -4,6 +4,15 @@
// "as is" without express or implied warranty, and with no claim as // "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose. // to its suitability for any purpose.
//
// This file checks to see if various standard container
// implementations live up to requirements specified in the C++
// standard. As many implementations do not live to the requirements,
// it is not uncommon for this file to fail to compile. The
// BOOST_HIDE_EXPECTED_ERRORS macro is provided here if you want to
// see as much of this file compile as possible.
//
#include <boost/pending/concept_checks.hpp> #include <boost/pending/concept_checks.hpp>
#include <iterator> #include <iterator>
@@ -16,10 +25,12 @@
#include <slist> #include <slist>
#endif #endif
//#define BOOST_HIDE_EXPECTED_ERRORS
int int
main() main()
{ {
#if defined(_ITERATOR_) #if defined(_ITERATOR_) && defined(BOOST_HIDE_EXPECTED_ERRORS)
// VC++ STL implementation is not standard conformant and // VC++ STL implementation is not standard conformant and
// fails to pass these concept checks // fails to pass these concept checks
#else #else
@@ -28,27 +39,27 @@ main()
typedef std::list<int> List; typedef std::list<int> List;
// VC++ missing pointer and const_pointer typedefs // VC++ missing pointer and const_pointer typedefs
REQUIRE(Vector, Mutable_RandomAccessContainer); BOOST_FUNCTION_REQUIRES(Vector, Mutable_RandomAccessContainerConcept);
REQUIRE(Vector, BackInsertionSequence); BOOST_FUNCTION_REQUIRES(Vector, BackInsertionSequenceConcept);
#if !defined(__GNUC__) #if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS))
#if !defined __sgi #if !(defined(__sgi) && defined(BOOST_HIDE_EXPECTED_ERRORS))
// old deque iterator missing n + iter operation // old deque iterator missing n + iter operation
REQUIRE(Deque, Mutable_RandomAccessContainer); BOOST_FUNCTION_REQUIRES(Deque, Mutable_RandomAccessContainerConcept);
#endif #endif
// warnings about signed and unsigned in old deque version // warnings about signed and unsigned in old deque version
REQUIRE(Deque, FrontInsertionSequence); BOOST_FUNCTION_REQUIRES(Deque, FrontInsertionSequenceConcept);
REQUIRE(Deque, BackInsertionSequence); BOOST_FUNCTION_REQUIRES(Deque, BackInsertionSequenceConcept);
#endif #endif
// VC++ missing pointer and const_pointer typedefs // VC++ missing pointer and const_pointer typedefs
REQUIRE(List, Mutable_ReversibleContainer); BOOST_FUNCTION_REQUIRES(List, Mutable_ReversibleContainerConcept);
REQUIRE(List, FrontInsertionSequence); BOOST_FUNCTION_REQUIRES(List, FrontInsertionSequenceConcept);
REQUIRE(List, BackInsertionSequence); BOOST_FUNCTION_REQUIRES(List, BackInsertionSequenceConcept);
#ifndef BOOST_NO_SLIST #ifndef BOOST_NO_SLIST
typedef std::slist<int> SList; typedef std::slist<int> SList;
REQUIRE(SList, FrontInsertionSequence); BOOST_FUNCTION_REQUIRES(SList, FrontInsertionSequenceConcept);
#endif #endif
typedef std::set<int> Set; typedef std::set<int> Set;
@@ -56,21 +67,21 @@ main()
typedef std::map<int,int> Map; typedef std::map<int,int> Map;
typedef std::multimap<int,int> MultiMap; typedef std::multimap<int,int> MultiMap;
REQUIRE(Set, SortedAssociativeContainer); BOOST_FUNCTION_REQUIRES(Set, SortedAssociativeContainerConcept);
REQUIRE(Set, SimpleAssociativeContainer); BOOST_FUNCTION_REQUIRES(Set, SimpleAssociativeContainerConcept);
REQUIRE(Set, UniqueAssociativeContainer); BOOST_FUNCTION_REQUIRES(Set, UniqueAssociativeContainerConcept);
REQUIRE(MultiSet, SortedAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiSet, SortedAssociativeContainerConcept);
REQUIRE(MultiSet, SimpleAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiSet, SimpleAssociativeContainerConcept);
REQUIRE(MultiSet, MultipleAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiSet, MultipleAssociativeContainerConcept);
REQUIRE(Map, SortedAssociativeContainer); BOOST_FUNCTION_REQUIRES(Map, SortedAssociativeContainerConcept);
REQUIRE(Map, UniqueAssociativeContainer); BOOST_FUNCTION_REQUIRES(Map, UniqueAssociativeContainerConcept);
REQUIRE(Map, PairAssociativeContainer); BOOST_FUNCTION_REQUIRES(Map, PairAssociativeContainerConcept);
REQUIRE(MultiMap, SortedAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiMap, SortedAssociativeContainerConcept);
REQUIRE(MultiMap, MultipleAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiMap, MultipleAssociativeContainerConcept);
REQUIRE(MultiMap, PairAssociativeContainer); BOOST_FUNCTION_REQUIRES(MultiMap, PairAssociativeContainerConcept);
#endif #endif
return 0; return 0;

View File

@@ -21,51 +21,6 @@ main()
{ {
using namespace boost; using namespace boost;
//===========================================================================
// First verify that the archetype classes model the concepts they
// are suppose to.
{
REQUIRE2(boolean_archetype, bool, Convertible);
}
{
typedef unary_function_archetype<int, int> F;
REQUIRE3(F, int, int, UnaryFunction);
}
{
typedef binary_function_archetype<int, int, int> F;
REQUIRE4(F, int, int, int, BinaryFunction);
}
{
typedef unary_predicate_archetype<int> F;
REQUIRE2(F, int, UnaryPredicate);
}
{
typedef binary_predicate_archetype<int, int> F;
REQUIRE3(F, int, int, BinaryPredicate);
typedef const_binary_predicate_archetype<int, int> const_F;
REQUIRE3(const_F, int, int, Const_BinaryPredicate);
}
{
typedef input_iterator_archetype<null_archetype> Iter;
REQUIRE(Iter, InputIterator);
}
{
typedef output_iterator_archetype Iter;
REQUIRE2(Iter, int, OutputIterator);
}
{
typedef forward_iterator_archetype<null_archetype> Iter;
REQUIRE(Iter, ForwardIterator);
}
{
typedef bidirectional_iterator_archetype<null_archetype> Iter;
REQUIRE(Iter, BidirectionalIterator);
}
{
typedef random_access_iterator_archetype<null_archetype> Iter;
REQUIRE(Iter, RandomAccessIterator);
}
//=========================================================================== //===========================================================================
// Non-mutating Algorithms // Non-mutating Algorithms
{ {
@@ -75,17 +30,17 @@ main()
} }
{ {
/* /*
SGI STL Docs and the C++ standard (25.1.2) requirements for SGI STL Docs and the C++ standard (25.1.2) BOOST_FUNCTION_REQUIRESments for
std::for_each() are broken. They should be specified as follows: std::for_each() are broken. They should be specified as follows:
template <class InputIterator, class LeftEqualityComparable> template <class InputIterator, class LeftEqualityComparable>
InputIterator find(InputIterator first, InputIterator last, InputIterator find(InputIterator first, InputIterator last,
const LeftEqualityComparable& value) const LeftEqualityComparable& value)
{ {
REQUIRE(InputIterator, InputIterator); BOOST_FUNCTION_REQUIRES(InputIterator, InputIterator);
typedef typename std::iterator_traits<InputIterator>::value_type typedef typename std::iterator_traits<InputIterator>::value_type
value_type; value_type;
REQUIRE(LeftEqualityComparable, value_type, LeftEqualityComparable); BOOST_FUNCTION_REQUIRES(LeftEqualityComparable, value_type, LeftEqualityComparable);
... ...
} }
*/ */
@@ -119,10 +74,11 @@ main()
{ {
typedef input_iterator_archetype<null_archetype> InIter; typedef input_iterator_archetype<null_archetype> InIter;
InIter in; InIter in;
REQUIRE(InIter, InputIterator); BOOST_FUNCTION_REQUIRES(InIter, InputIteratorConcept);
left_equality_comparable_archetype<null_archetype> value(dummy_cons); left_equality_comparable_archetype<null_archetype> value(dummy_cons);
std::iterator_traits<InIter>::difference_type std::iterator_traits<InIter>::difference_type
n = std::count(in, in, value); n = std::count(in, in, value);
ignore_unused_variable_warning(n);
} }
{ {
typedef input_iterator_archetype<null_archetype> InIter; typedef input_iterator_archetype<null_archetype> InIter;
@@ -137,6 +93,7 @@ main()
unary_predicate_archetype<null_archetype> pred; unary_predicate_archetype<null_archetype> pred;
std::iterator_traits<InIter>::difference_type std::iterator_traits<InIter>::difference_type
n = std::count_if(in, in, pred); n = std::count_if(in, in, pred);
ignore_unused_variable_warning(n);
} }
{ {
input_iterator_archetype< convertible_to_archetype<null_archetype> > in; input_iterator_archetype< convertible_to_archetype<null_archetype> > in;
@@ -154,12 +111,14 @@ main()
typedef input_iterator_archetype<Right> InIter2; typedef input_iterator_archetype<Right> InIter2;
InIter2 in2; InIter2 in2;
std::pair<InIter1, InIter2> p = std::mismatch(in1, in1, in2); std::pair<InIter1, InIter2> p = std::mismatch(in1, in1, in2);
ignore_unused_variable_warning(p);
} }
{ {
typedef input_iterator_archetype< convertible_to_archetype<null_archetype> > InIter; typedef input_iterator_archetype< convertible_to_archetype<null_archetype> > InIter;
InIter in1, in2; InIter in1, in2;
binary_predicate_archetype<null_archetype, null_archetype> pred; binary_predicate_archetype<null_archetype, null_archetype> pred;
std::pair<InIter, InIter> p = std::mismatch(in1, in1, in2, pred); std::pair<InIter, InIter> p = std::mismatch(in1, in1, in2, pred);
ignore_unused_variable_warning(p);
} }
{ {
// SGI STL docs: EqualityComparable not needed // SGI STL docs: EqualityComparable not needed
@@ -167,11 +126,13 @@ main()
typedef left_equality_comparable_archetype<null_archetype> Right; typedef left_equality_comparable_archetype<null_archetype> Right;
input_iterator_archetype<Right> in2; input_iterator_archetype<Right> in2;
bool b = std::equal(in1, in1, in2); bool b = std::equal(in1, in1, in2);
ignore_unused_variable_warning(b);
} }
{ {
input_iterator_archetype< convertible_to_archetype<null_archetype> > in1, in2; input_iterator_archetype< convertible_to_archetype<null_archetype> > in1, in2;
binary_predicate_archetype<null_archetype, null_archetype> pred; binary_predicate_archetype<null_archetype, null_archetype> pred;
bool b = std::equal(in1, in1, in2, pred); bool b = std::equal(in1, in1, in2, pred);
ignore_unused_variable_warning(b);
} }
{ {
// SGI STL docs: EqualityComparable not needed // SGI STL docs: EqualityComparable not needed