diff --git a/concept_checking.html b/concept_checking.html index 57d71a0..accd03e 100644 --- a/concept_checking.html +++ b/concept_checking.html @@ -51,7 +51,8 @@ The documentation is organized into the following sections.
  • Implementation
  • Reference
    1. -
    2. Macros
    3. +
    4. Functions
    5. +
    6. Classes
    7. Basic Concept Checking Classes
    8. Iterator Concept Checking Classes
    9. Function Object Concept Checking Classes
    10. @@ -101,14 +102,6 @@ Library uses some standard C++ constructs to enforce early concept compliance and that provides more informative error messages upon non-compliance. - -

      Note that this technique only addresses the syntactic requirements of concepts (the valid expressions and associated types). @@ -234,55 +227,76 @@ RandomAccessIterator).

      Using Concept Checks

      -The Boost Concept Checking Library defines several macros that make it -convenient to ensure that some type (or collection of types) models a -given concept. The REQUIRE macros can be used in function -bodies and the CLASS_REQUIRES macros can be used in class -bodies. The purpose of the macros is to check that the given -type models the specified concept. We use macros so -that the checks can be conditionally removed in situations where -faster compile time is needed. +For each concept there is a concept checking class which can be used +to make sure that a given type (or set of types) models the concept. +The Boost Concept Checking Library includes concept checking classes +for all of the concepts used in the C++ standard library and a few +more. The Reference section below lists these +concept checking classes. In addition, other boost libraries come with +concept checking classes for the concepts that are particular to those +libraries. An example of one of these classes is the +EqualityComparableConcept class.
      -  REQUIRE(type, concept);
      -  REQUIRE2(type1, type2, concept);
      -  REQUIRE3(type1, type2, type3, concept);
      -  REQUIRE4(type1, type2, type3, type4, concept);
      +  template <class T> struct EqualityComparableConcept;
      +
      - CLASS_REQUIRES(type, concept); - CLASS_REQUIRES2(type1, type2, concept); - CLASS_REQUIRES3(type1, type2, type3, concept); - CLASS_REQUIRES4(type1, type2, type3, type4, concept); +Each concept checking class has a member function named +constraints() which contains the valid expressions for the +concept. To check whether some type, say foo, is +EqualityComparable, we need to instantiate the concept checking class +with foo: EqualityComparableConcept<foo> and then find +a way to get the compiler to compile the constraints() +function without actually calling it. The Boost Concept Checking +Library defines two utilities that make this easy: +function_requires() and class_requires. +function_requires() function can be used in function bodies +and the class_requires class can be used inside class +bodies. The function_requires() function takes no arguments, +but has a template parameter for the concept checking class. This +means that the instantiated concept checking class must be given as an +explicit template argument, as shown below. + +
      +  void some_function_using_foo() {
      +    function_requires< EqualityComparableConcept<foo> >();
      +    // ...
      +  };
      +
      + +The class_requires is a class template with a template +parameter for the concept checking class. Accessing the nested +check type within class_requires triggers the the +concept checking. + +
      +  struct some_class_using_foo {
      +    typedef class_requires< EqualityComparableConcept<foo> >::check req1;
      +  };
       
      To add concept checks to the std::stable_sort() function the -library implementor would simply insert REQUIRE at the top of -std::stable_sort() to make sure the template parameter type -models +library implementor would simply insert function_requires() +at the top of std::stable_sort() to make sure the template +parameter type models RandomAccessIterator. In addition, std::stable_sort() requires that the value_type of the iterators be -LessThanComparable, so we also use REQUIRE to check this. +LessThanComparable, so we also use function_requires() to +check this.
         template <class RandomAccessIter>
         void stable_sort(RandomAccessIter first, RandomAccessIter last)
         {
      -    REQUIRE(RandomAccessIter, RandomAccessIterator);
      +    function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();
           typedef typename std::iterator_traits<RandomAccessIter>::value_type value_type;
      -    REQUIRE(value_type, LessThanComparable);
      +    function_requires< LessThanComparableConcept<value_type> >();
           ...
         }
       
      -The Boost Concept Checking library includes a concept checking class -for each of the concepts described in the SGI STL documentation. The -second argument to REQUIRE indicates which concept checking -class should be used. In the above example, the use of -LessThanComparable indicates that the -LessThanComparable_concept class will be used to check the -value type. The Reference section below -lists the concept checking classes.

      Some concepts deal with more than one type. In this case the corresponding concept checking class will have multiple template -parameters. The following example shows how the REQUIRE2 -macro is used with the function_requires() is used with the ReadWritePropertyMap concept which takes two type parameters: a property map and the key type for the map. @@ -306,24 +320,25 @@ type for the map. Buffer& Q, BFSVisitor vis, ColorMap color) { typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex; - REQUIRE2(ColorMap, Vertex, ReadWritePropertyMap); + function_requires< ReadWritePropertyMap<ColorMap, Vertex> >(); ... } -As an example of using the CLASS_REQUIRES macro we look at a -concept check that could be added to std::vector. One -requirement that is placed on the element type is that it must be class_requires we look at a concept +check that could be added to std::vector. One requirement +that is placed on the element type is that it must be Assignable. -We can check this by inserting CLASS_REQUIRES(T, Assignable) -at the top of the definition for std::vector. +We can check this by inserting +class_requires<AssignableConcept<T> > at the top +of the definition for std::vector.

         namespace std {
           template <class T>
           struct vector {
      -      CLASS_REQUIRES(T, Assignable);
      +      typedef typename class_requires< AssignableConcept<T> >::check req;
             ...
           };
         }
      @@ -333,9 +348,10 @@ at the top of the definition for std::vector.
       Although the concept checks are designed for use by generic library
       implementors, they can also be useful to end users. Sometimes one may
       not be sure whether some type models a particular concept. This can
      -easily be checked by creating a small program and using the
      -REQUIRE macro with the type and concept in question.  The
      -file stl_concept_checks.cpp
      +easily be checked by creating a small program and using
      +function_requires() with the type and concept in question.
      +The file stl_concept_checks.cpp
       gives and example of applying the concept checks to STL
       containers. The file is listed here:
       
      @@ -356,37 +372,37 @@ containers. The file is listed here:
           typedef std::deque<int> Deque;
           typedef std::list<int> List;
       
      -    REQUIRE(Vector, Mutable_RandomAccessContainer);
      -    REQUIRE(Vector, BackInsertionSequence);
      +    function_requires< Mutable_RandomAccessContainer<Vector> >();
      +    function_requires< BackInsertionSequence<Vector> >();
       
      -    REQUIRE(Deque, Mutable_RandomAccessContainer);
      -    REQUIRE(Deque, FrontInsertionSequence);
      -    REQUIRE(Deque, BackInsertionSequence);
      +    function_requires< Mutable_RandomAccessContainer<Deque> >();
      +    function_requires< FrontInsertionSequence<Deque> >();
      +    function_requires< BackInsertionSequence<Deque> >();
       
      -    REQUIRE(List, Mutable_ReversibleContainer);
      -    REQUIRE(List, FrontInsertionSequence);
      -    REQUIRE(List, BackInsertionSequence);
      +    function_requires< Mutable_ReversibleContainer<List> >();
      +    function_requires< FrontInsertionSequence<List> >();
      +    function_requires< BackInsertionSequence<List> >();
       
           typedef std::set<int> Set;
           typedef std::multiset<int> MultiSet;
           typedef std::map<int,int> Map;
           typedef std::multimap<int,int> MultiMap;
       
      -    REQUIRE(Set, SortedAssociativeContainer);
      -    REQUIRE(Set, SimpleAssociativeContainer);
      -    REQUIRE(Set, UniqueAssociativeContainer);
      +    function_requires< SortedAssociativeContainer<Set> >();
      +    function_requires< SimpleAssociativeContainer<Set> >();
      +    function_requires< UniqueAssociativeContainer<Set> >();
       
      -    REQUIRE(MultiSet, SortedAssociativeContainer);
      -    REQUIRE(MultiSet, SimpleAssociativeContainer);
      -    REQUIRE(MultiSet, MultipleAssociativeContainer);
      +    function_requires< SortedAssociativeContainer<MultiSet> >();
      +    function_requires< SimpleAssociativeContainer<MultiSet> >();
      +    function_requires< MultipleAssociativeContainer<MultiSet> >();
       
      -    REQUIRE(Map, SortedAssociativeContainer);
      -    REQUIRE(Map, UniqueAssociativeContainer);
      -    REQUIRE(Map, PairAssociativeContainer);
      +    function_requires< SortedAssociativeContainer<Map> >();
      +    function_requires< UniqueAssociativeContainer<Map> >();
      +    function_requires< PairAssociativeContainer<Map> >();
       
      -    REQUIRE(MultiMap, SortedAssociativeContainer);
      -    REQUIRE(MultiMap, MultipleAssociativeContainer);
      -    REQUIRE(MultiMap, PairAssociativeContainer);
      +    function_requires< SortedAssociativeContainer<MultiMap> >();
      +    function_requires< MultipleAssociativeContainer<MultiMap> >();
      +    function_requires< PairAssociativeContainer<MultiMap> >();
       
           return 0;
         }
      @@ -434,10 +450,11 @@ enforce the associated types of the concept.
         struct RandomAccessIterator_concept
         {
           void constraints() {
      -      REQUIRE(Iter, BidirectionalIterator);
      -      REQUIRE(Iter, LessThanComparable);
      -      REQUIRE2(typename std::iterator_traits<Iter>::iterator_category,
      -        std::random_access_iterator_tag, Convertible);
      +      function_requires< BidirectionalIteratorConcept<Iter> >();
      +      function_requires< LessThanComparableConcept<Iter> >();
      +      function_requires< ConvertibleConcept<
      +        typename std::iterator_traits<Iter>::iterator_category,
      +        std::random_access_iterator_tag> >();
       
             i += n;
             i = i + n; i = n + i;
      @@ -739,8 +756,9 @@ We can still use the function pointer mechanism to cause instantiation
       of the constraints function, however now it will be a member function
       pointer. To make it easy for the library implementor to invoke the
       concept checks, we wrap the member function pointer mechanism in a
      -macro named REQUIRE. The following code snippet shows how to
      -use REQUIRE to make sure that the iterator is a
      +function named function_requires(). The following code
      +snippet shows how to use function_requires() to make sure
      +that the iterator is a
       
       RandomAccessIterator.
      @@ -749,155 +767,156 @@ RandomAccessIterator.
         template <class RandomAccessIter>
         void stable_sort(RandomAccessIter first, RandomAccessIter last)
         {
      -    REQUIRE(RandomAccessIter, RandomAccessIterator);
      +    function_requires< RandomAccessIteratorConcept >();
           ...
         }
       
      -The definition of the REQUIRE is as follows. The -type_var is the type we wish to check, and concept -is the name that corresponds to the concept checking class. We assign -the address of the constraints member function to the function pointer -x, which causes the instantiation of the constraints function -and checking of the concept's valid expressions. We then assign -x to x to avoid unused variable compiler warnings, -and wrap everything in a do-while loop to prevent name collisions. +The definition of the function_requires() is as follows. The +Concept is the concept checking class that has been +instantiated with the modeling type. We assign the address of the +constraints member function to the function pointer x, which +causes the instantiation of the constraints function and checking of +the concept's valid expressions. We then assign x to +x to avoid unused variable compiler warnings, and wrap +everything in a do-while loop to prevent name collisions.
      -  #define REQUIRE(type_var, concept)                \
      -  do {                                              \
      -    void (concept##_concept <type_var>::*x)() =     \
      -      concept##_concept <type_var>::constraints;    \
      -    x = x;                                          \
      -  } while (0)
      +  template 
      +  void function_requires()
      +  {
      +    void (Concept::*x)() = BOOST_FPTR Concept::constraints;
      +    ignore_unused_variable_warning(x);
      +  }
       
      To check the type parameters of class templates, we provide the -CLASS_REQUIRES macro which can be used inside the body of a -class definition (whereas the REQUIRES macro can only be used -inside of a function body). This macro declares a nested class -template, where the template parameter is a function pointer. We then -use the nested class type in a typedef with the function pointer type -of the constraint function as the template argument. We use the -type_var and concept names in the nested class and -typedef names to help prevent name collisions. +class_requires class which can be used inside the body of a +class definition (whereas function_requires() can only be +used inside of a function body). class_requires declares a +nested class template, where the template parameter is a function +pointer. We then use the nested class type in a typedef with the +function pointer type of the constraint function as the template +argument.
      -  #define CLASS_REQUIRES(type_var, concept)          \
      -    typedef void (concept##_concept <type_var>       \
      -      ::* func##type_var##concept)();                \
      -                                                     \
      -    template <func##type_var##concept FuncPtr>       \
      -    struct dummy_struct_##type_var##concept { };     \
      -                                                     \
      -    typedef dummy_struct_##type_var##concept<        \
      -      concept##_concept <type_var>::constraints>     \
      -      dummy_typedef_##type_var##concept
      +  template <class Concept>
      +  class class_requires
      +  {
      +    typedef void (Concept::* function_pointer)();
      +
      +    template <function_pointer Fptr>
      +    struct dummy_struct { };
      +  public:
      +    typedef dummy_struct< BOOST_FPTR Concept::constraints > check;
      +  };
       
      -In addition, there are versions of REQUIRE and -CLASS_REQUIRES that take more arguments, to handle concepts -that include interactions between two or more types. -CLASS_REQUIRES was not used in the implementation of the STL -concept checks because several compilers do not implement template -parameters of function pointer type. - +class_requires was not used in the implementation of the +Boost Concept Checking Library concept checks because several +compilers do not implement template parameters of function pointer +type.

      Reference

      -

      Macros

      +

      Functions

      -  // Apply concept checks in function definitions.
      -  REQUIRE(type, concept);
      -  REQUIRE2(type1, type2, concept);
      -  REQUIRE3(type1, type2, type3, concept);
      -  REQUIRE4(type1, type2, type3, type4, concept);
      +  template <class Concept>
      +  void function_requires();
      +
      + +

      Classes

      +
      +  template <class Concept>
      +  struct class_requires {
      +    typedef ... check;
      +  };
       
      -  // Apply concept checks in class definitions.
      -  CLASS_REQUIRES(type, concept);
      -  CLASS_REQUIRES2(type1, type2, concept);
      -  CLASS_REQUIRES3(type1, type2, type3, concept);
      -  CLASS_REQUIRES4(type1, type2, type3, type4, concept);
      -
      - -
      -  // Make sure that type1 and type2 are exactly the same type
      -  REQUIRE_SAME_TYPE(type1, type2);
      +  // Make sure that Type1 and Type2 are exactly the same type.
      +  // If they are not, then the nested typedef for type will
      +  // not exist and cause a compiler error.
      +  template <class Type1, class Type2>
      +  struct require_same {
      +    typedef ... type;
      +  };
      +  // usage example
      +  typedef typedef require_same::type req1; // this will compile OK
      +  typedef typedef require_same::type req1; // this will cause a compiler error
       

      Basic Concept Checking Classes

         template <class T> struct Integer_concept; // Is T a built-in integer type?
      -  template <class T> struct SignedInteger_concept; // Is T a built-in signed integer type?
      -  template <class X, class Y> struct Convertible_concept; // Is X convertible to Y?
      -  template <class T> struct Assignable_concept;
      -  template <class T> struct DefaultConstructible_concept;
      -  template <class T> struct CopyConstructible_concept;
      -  template <class T> struct Boolean_concept;
      -  template <class T> struct EqualityComparable_concept;
      +  template <class T> struct SignedIntegerConcept; // Is T a built-in signed integer type?
      +  template <class X, class Y> struct ConvertibleConcept; // Is X convertible to Y?
      +  template <class T> struct AssignableConcept;
      +  template <class T> struct DefaultConstructibleConcept;
      +  template <class T> struct CopyConstructibleConcept;
      +  template <class T> struct BooleanConcept;
      +  template <class T> struct EqualityComparableConcept;
         // Is class T equality comparable on the left side with type Left?
      -  template <class T, class Left> struct LeftEqualityComparable_concept;
      -  template <class T> struct LessThanComparable_concept;
      +  template <class T, class Left> struct LeftEqualityComparableConcept;
      +  template <class T> struct LessThanComparableConcept;
       

      Iterator Concept Checking Classes

      -  template <class Iter> struct TrivialIterator_concept;
      -  template <class Iter> struct Mutable_TrivialIterator_concept;
      -  template <class Iter> struct InputIterator_concept;
      -  template <class Iter, class T> struct OutputIterator_concept;
      -  template <class Iter> struct ForwardIterator_concept;
      -  template <class Iter> struct Mutable_ForwardIterator_concept;
      -  template <class Iter> struct BidirectionalIterator_concept;
      -  template <class Iter> struct Mutable_BidirectionalIterator_concept;
      -  template <class Iter> struct RandomAccessIterator_concept;
      -  template <class Iter> struct Mutable_RandomAccessIterator_concept;
      +  template <class Iter> struct TrivialIteratorConcept;
      +  template <class Iter> struct Mutable_TrivialIteratorConcept;
      +  template <class Iter> struct InputIteratorConcept;
      +  template <class Iter, class T> struct OutputIteratorConcept;
      +  template <class Iter> struct ForwardIteratorConcept;
      +  template <class Iter> struct Mutable_ForwardIteratorConcept;
      +  template <class Iter> struct BidirectionalIteratorConcept;
      +  template <class Iter> struct Mutable_BidirectionalIteratorConcept;
      +  template <class Iter> struct RandomAccessIteratorConcept;
      +  template <class Iter> struct Mutable_RandomAccessIteratorConcept;
       

      Function Object Concept Checking Classes

      -  template <class Func, class Return> struct Generator_concept;
      -  template <class Func, class Return, class Arg> struct UnaryFunction_concept;
      -  template <class Func, class Return, class First, class Second> struct BinaryFunction_concept;
      -  template <class Func, class Arg> struct UnaryPredicate_concept;
      -  template <class Func, class First, class Second> struct BinaryPredicate_concept;
      -  template <class Func, class First, class Second> struct Const_BinaryPredicate_concept {;
      +  template <class Func, class Return> struct GeneratorConcept;
      +  template <class Func, class Return, class Arg> struct UnaryFunctionConcept;
      +  template <class Func, class Return, class First, class Second> struct BinaryFunctionConcept;
      +  template <class Func, class Arg> struct UnaryPredicateConcept;
      +  template <class Func, class First, class Second> struct BinaryPredicateConcept;
      +  template <class Func, class First, class Second> struct Const_BinaryPredicateConcept {;
       

      Container Concept Checking Classes

      -  template <class C> struct Container_concept;
      -  template <class C> struct Mutable_Container_concept;
      +  template <class C> struct ContainerConcept;
      +  template <class C> struct Mutable_ContainerConcept;
       
      -  template <class C> struct ForwardContainer_concept;
      -  template <class C> struct Mutable_ForwardContainer_concept;
      +  template <class C> struct ForwardContainerConcept;
      +  template <class C> struct Mutable_ForwardContainerConcept;
       
      -  template <class C> struct ReversibleContainer_concept;
      -  template <class C> struct Mutable_ReversibleContainer_concept;
      +  template <class C> struct ReversibleContainerConcept;
      +  template <class C> struct Mutable_ReversibleContainerConcept;
       
      -  template <class C> struct RandomAccessContainer_concept;
      -  template <class C> struct Mutable_RandomAccessContainer_concept;
      +  template <class C> struct RandomAccessContainerConcept;
      +  template <class C> struct Mutable_RandomAccessContainerConcept;
       
      -  template <class C> struct Sequence_concept;
      -  template <class C> struct FrontInsertionSequence_concept;
      -  template <class C> struct BackInsertionSequence_concept;
      +  template <class C> struct SequenceConcept;
      +  template <class C> struct FrontInsertionSequenceConcept;
      +  template <class C> struct BackInsertionSequenceConcept;
       
      -  template <class C> struct AssociativeContainer_concept;
      -  template <class C> struct UniqueAssociativeContainer_concept;
      -  template <class C> struct MultipleAssociativeContainer_concept;
      -  template <class C> struct SimpleAssociativeContainer_concept;
      -  template <class C> struct PairAssociativeContainer_concept;
      -  template <class C> struct SortedAssociativeContainer_concept;
      +  template <class C> struct AssociativeContainerConcept;
      +  template <class C> struct UniqueAssociativeContainerConcept;
      +  template <class C> struct MultipleAssociativeContainerConcept;
      +  template <class C> struct SimpleAssociativeContainerConcept;
      +  template <class C> struct PairAssociativeContainerConcept;
      +  template <class C> struct SortedAssociativeContainerConcept;
       
      diff --git a/stl_concept_checks.cpp b/stl_concept_checks.cpp index f8a64ee..021e428 100644 --- a/stl_concept_checks.cpp +++ b/stl_concept_checks.cpp @@ -25,11 +25,13 @@ #include #endif -//#define BOOST_HIDE_EXPECTED_ERRORS +#define BOOST_HIDE_EXPECTED_ERRORS int main() { + using namespace boost; + #if defined(_ITERATOR_) && defined(BOOST_HIDE_EXPECTED_ERRORS) // VC++ STL implementation is not standard conformant and // fails to pass these concept checks @@ -39,27 +41,27 @@ main() typedef std::list List; // VC++ missing pointer and const_pointer typedefs - BOOST_FUNCTION_REQUIRES(Vector, Mutable_RandomAccessContainerConcept); - BOOST_FUNCTION_REQUIRES(Vector, BackInsertionSequenceConcept); + function_requires< Mutable_RandomAccessContainerConcept >(); + function_requires< BackInsertionSequenceConcept >(); #if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS)) #if !(defined(__sgi) && defined(BOOST_HIDE_EXPECTED_ERRORS)) // old deque iterator missing n + iter operation - BOOST_FUNCTION_REQUIRES(Deque, Mutable_RandomAccessContainerConcept); + function_requires< Mutable_RandomAccessContainerConcept >(); #endif // warnings about signed and unsigned in old deque version - BOOST_FUNCTION_REQUIRES(Deque, FrontInsertionSequenceConcept); - BOOST_FUNCTION_REQUIRES(Deque, BackInsertionSequenceConcept); + function_requires< FrontInsertionSequenceConcept >(); + function_requires< BackInsertionSequenceConcept >(); #endif // VC++ missing pointer and const_pointer typedefs - BOOST_FUNCTION_REQUIRES(List, Mutable_ReversibleContainerConcept); - BOOST_FUNCTION_REQUIRES(List, FrontInsertionSequenceConcept); - BOOST_FUNCTION_REQUIRES(List, BackInsertionSequenceConcept); + function_requires< Mutable_ReversibleContainerConcept >(); + function_requires< FrontInsertionSequenceConcept >(); + function_requires< BackInsertionSequenceConcept >(); #ifndef BOOST_NO_SLIST typedef std::slist SList; - BOOST_FUNCTION_REQUIRES(SList, FrontInsertionSequenceConcept); + function_requires< FrontInsertionSequenceConcept >(); #endif typedef std::set Set; @@ -67,21 +69,21 @@ main() typedef std::map Map; typedef std::multimap MultiMap; - BOOST_FUNCTION_REQUIRES(Set, SortedAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(Set, SimpleAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(Set, UniqueAssociativeContainerConcept); + function_requires< SortedAssociativeContainerConcept >(); + function_requires< SimpleAssociativeContainerConcept >(); + function_requires< UniqueAssociativeContainerConcept >(); - BOOST_FUNCTION_REQUIRES(MultiSet, SortedAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(MultiSet, SimpleAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(MultiSet, MultipleAssociativeContainerConcept); + function_requires< SortedAssociativeContainerConcept >(); + function_requires< SimpleAssociativeContainerConcept >(); + function_requires< MultipleAssociativeContainerConcept >(); - BOOST_FUNCTION_REQUIRES(Map, SortedAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(Map, UniqueAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(Map, PairAssociativeContainerConcept); + function_requires< SortedAssociativeContainerConcept >(); + function_requires< UniqueAssociativeContainerConcept >(); + function_requires< PairAssociativeContainerConcept >(); - BOOST_FUNCTION_REQUIRES(MultiMap, SortedAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(MultiMap, MultipleAssociativeContainerConcept); - BOOST_FUNCTION_REQUIRES(MultiMap, PairAssociativeContainerConcept); + function_requires< SortedAssociativeContainerConcept >(); + function_requires< MultipleAssociativeContainerConcept >(); + function_requires< PairAssociativeContainerConcept >(); #endif return 0; diff --git a/stl_concept_covering.cpp b/stl_concept_covering.cpp index 88cd1dd..0fe838a 100644 --- a/stl_concept_covering.cpp +++ b/stl_concept_covering.cpp @@ -30,17 +30,17 @@ main() } { /* - SGI STL Docs and the C++ standard (25.1.2) BOOST_FUNCTION_REQUIRESments for + SGI STL Docs and the C++ standard (25.1.2) requirements for std::for_each() are broken. They should be specified as follows: - template + template InputIterator find(InputIterator first, InputIterator last, - const LeftEqualityComparable& value) + const T& value) { - BOOST_FUNCTION_REQUIRES(InputIterator, InputIterator); + function_requires< InputIteratorConcept >(); typedef typename std::iterator_traits::value_type value_type; - BOOST_FUNCTION_REQUIRES(LeftEqualityComparable, value_type, LeftEqualityComparable); + function_requires< EqualityComparable2 >(); ... } */ @@ -74,7 +74,7 @@ main() { typedef input_iterator_archetype InIter; InIter in; - BOOST_FUNCTION_REQUIRES(InIter, InputIteratorConcept); + function_requires< InputIteratorConcept >(); left_equality_comparable_archetype value(dummy_cons); std::iterator_traits::difference_type n = std::count(in, in, value);