From 3e56a7c4ecdc68698b4207ccc575cfd7c5df11d3 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 21 Mar 2006 02:26:31 +0000 Subject: [PATCH 01/31] This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'. [SVN r33417] --- bibliography.html | 70 -- class_concept_checks_fail_expected.cpp | 30 - class_concept_checks_test.cpp | 37 - concept_checking.html | 999 ------------------------- concept_checks_fail_expected.cpp | 23 - concept_checks_test.cpp | 185 ----- stl_concept_checks.cpp | 90 --- stl_concept_checks.expected | 0 8 files changed, 1434 deletions(-) delete mode 100644 bibliography.html delete mode 100644 class_concept_checks_fail_expected.cpp delete mode 100644 class_concept_checks_test.cpp delete mode 100644 concept_checking.html delete mode 100644 concept_checks_fail_expected.cpp delete mode 100644 concept_checks_test.cpp delete mode 100644 stl_concept_checks.cpp delete mode 100644 stl_concept_checks.expected diff --git a/bibliography.html b/bibliography.html deleted file mode 100644 index 554a3a5..0000000 --- a/bibliography.html +++ /dev/null @@ -1,70 +0,0 @@ - - - -Boost Graph Library: Bibliography - -C++ Boost - -
- - -

Bibliography

- -
- -

1 -
Andrei Alexandrescu
-Better Template Error Messages.
-C/C++ Users Journal, March, 1999. - - -

2 -
Bjarne Stroustrup
-Design and Evolution of C++.
-Addison-Wesley, 1994 - -

3 -
-M. H. Austern. -
Generic Programming and the STL. -
Professional computing series. Addison-Wesley, 1999. - -

4 -
-David R. Musser and Atul Saini -
STL Tutorial and Reference Guide. -
Professional computing series. Addison-Wesley, 1996. - -

5 -
-A. A. Stepanov and M. Lee -
The Standard Template Library. -
ISO Programming Language C++ Project, May 1994. -
X3J16/94-0095, WG21/N0482 - - - -
- -
-
- - -
Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/class_concept_checks_fail_expected.cpp b/class_concept_checks_fail_expected.cpp deleted file mode 100644 index 24743d6..0000000 --- a/class_concept_checks_fail_expected.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// (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 - -/* - - This file verifies that class_requires of the Boost Concept Checking - Library catches errors when it is suppose to. - -*/ - -struct foo { }; - -using namespace boost; - -class class_requires_test -{ - BOOST_CLASS_REQUIRES(foo, EqualityComparableConcept); -}; - -int -main() -{ - class_requires_test x; - return 0; -} diff --git a/class_concept_checks_test.cpp b/class_concept_checks_test.cpp deleted file mode 100644 index 2eb3cce..0000000 --- a/class_concept_checks_test.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// (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 - -/* - - This file verifies that the BOOST_CLASS_REQUIRES macro of the Boost - Concept Checking Library does not cause errors when it is not suppose - to. - -*/ - -struct foo { bool operator()(int) { return true; } }; -struct bar { bool operator()(int, char) { return true; } }; - -using namespace boost; - -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; -} diff --git a/concept_checking.html b/concept_checking.html deleted file mode 100644 index d658842..0000000 --- a/concept_checking.html +++ /dev/null @@ -1,999 +0,0 @@ - - - -Concept Checking - -C++ Boost - -
- -

- -header -boost/concept_checks.hpp and -boost/concept_archetypes.hpp -

- -

-Generic programming in C++ is characterized by the use of template -parameters to represent abstract data types (or ``concepts''). -However, the C++ language itself does not provide a mechanism for -explicitly handling concepts. As a result, it can be difficult to -insure that a concrete type meets the requirements of the concept it -is supposed to represent. Error messages resulting from incorrect use -of a concrete type can be particularly difficult to decipher. The -Boost Concept Checking Library provides mechanisms for checking -parameters in C++ template libraries. The mechanisms use standard C++ -and introduce no run-time overhead. The main cost of using the -mechanism is in compile-time. - -The documentation is organized into the following sections. - -

    -
  1. Introduction
  2. -
  3. Motivating Example
  4. -
  5. Using Concept Checks
  6. -
  7. Creating Concept Checking Classes
  8. -
  9. Concept Covering and Archetypes
  10. -
  11. Programming With Concepts
  12. -
  13. Implementation
  14. -
  15. Reference
  16. -
      -
    1. Functions
    2. -
    3. Classes
    4. -
    5. Basic Concept Checking Classes
    6. -
    7. Iterator Concept Checking Classes
    8. -
    9. Function Object Concept Checking Classes
    10. -
    11. Container Concept Checking Classes
    12. -
    13. Basic Archetype Classes
    14. -
    15. Iterator Archetype Classes
    16. -
    17. Function Object Archetype Classes
    18. -
    19. Container Archetype Classes
    20. -
    -
  17. History
  18. -
  19. Publications
  20. -
  21. Acknowledgements
  22. -
- -

-Jeremy Siek -contributed this library. X managed the formal review. - -

Introduction

- -A concept is a set of requirements (valid expressions, -associated types, semantic invariants, complexity guarantees, etc.) -that a type must fulfill to be correctly used as arguments in a call -to a generic algorithm. In C++, concepts are represented by formal -template parameters to function templates (generic algorithms). -However, C++ has no explicit mechanism for representing concepts --- -template parameters are merely placeholders. By convention, these -parameters are given names corresponding to the concept that is -required, but a C++ compiler does not enforce compliance to the -concept when the template parameter is bound to an actual type. - -

-Naturally, if a generic algorithm is invoked with a type that does not -fulfill at least the syntactic requirements of the concept, a -compile-time error will occur. However, this error will not per - se reflect the fact that the type did not meet all of the -requirements of the concept. Rather, the error may occur deep inside -the instantiation hierarchy at the point where an expression is not -valid for the type, or where a presumed associated type is not -available. The resulting error messages are largely uninformative and -basically impenetrable. - -

-What is required is a mechanism for enforcing ``concept safety'' at -(or close to) the point of instantiation. The Boost Concept Checking -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). -We do not address the semantic invariants or complexity guarantees, -which are also part of concept requirements.. - -

Motivating Example

- -We present a simple example to illustrate incorrect usage of a -template library and the resulting error messages. In the code below, -the generic std::stable_sort() algorithm from the Standard -Template Library (STL)[3, 4,5] is applied to -a linked list. - -
-  bad_error_eg.cpp:
-   1  #include <list>
-   2  #include <algorithm>
-   3
-   4  struct foo {
-   5    bool operator<(const foo&) const { return false; }
-   6  };
-   7  int main(int, char*[]) {
-   8    std::list<foo> v;
-   9    std::stable_sort(v.begin(), v.end());
-  10    return 0;
-  11  }
-
- -Here, the -std::stable_sort() algorithm is prototyped as follows: -
-  template <class RandomAccessIterator>
-  void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
-
- -Attempting to compile this code with Gnu C++ produces the following -compiler error. The output from other compilers is listed in the -Appendix. - -
-stl_algo.h: In function `void __merge_sort_loop<_List_iterator
-  <foo,foo &,foo *>, foo *, int>(_List_iterator<foo,foo &,foo *>,
-  _List_iterator<foo,foo &,foo *>, foo *, int)':
-stl_algo.h:1448:   instantiated from `__merge_sort_with_buffer
-  <_List_iterator<foo,foo &,foo *>, foo *, int>(
-   _List_iterator<foo,foo &,foo *>, _List_iterator<foo,foo &,foo *>,
-   foo *, int *)'
-stl_algo.h:1485:   instantiated from `__stable_sort_adaptive<
-  _List_iterator<foo,foo &,foo *>, foo *, int>(_List_iterator
-  <foo,foo &,foo *>, _List_iterator<foo,foo &,foo *>, foo *, int)'
-stl_algo.h:1524:   instantiated from here
-stl_algo.h:1377: no match for `_List_iterator<foo,foo &,foo *> & -
-  _List_iterator<foo,foo &,foo *> &'
-
- -In this case, the fundamental error is that -std:list::iterator does not model the concept of -RandomAccessIterator. The list iterator is only bidirectional, not -fully random access (as would be a vector iterator). Unfortunately, -there is nothing in the error message to indicate this to the user. - -

-To a C++ programmer having enough experience with template libraries -the error may be obvious. However, for the uninitiated, there are several -reasons why this message would be hard to understand. - -

    -
  1. The location of the error, line 9 of bad_error_eg.cpp - is not pointed to by the error message, despite the fact that Gnu C++ - prints up to 4 levels deep in the instantiation stack. -
  2. There is no textual correlation between the error message and the - documented requirements for std::stable_sort() and for - -RandomAccessIterator. -
  3. The error message is overly long, listing functions internal - to the STL that the user does not (and should not!) know or care - about. -
  4. With so many internal library functions listed in the error - message, the programmer could easily infer that the error is due - to the library, rather than to his or her own code. -
- -The following is an example of what we might expect from a more -informative message (and is in fact what the Boost Concept Checking -Library produces): - -
-concept_checks.hpp: In method `void LessThanComparable_concept
-  <_List_iterator<foo,foo &,foo *> >::constraints()':
-concept_checks.hpp:334:   instantiated from `RandomAccessIterator_concept
-  <_List_iterator<foo,foo &,foo *> >::constraints()'
-bad_error_eg.cpp:9:   instantiated from `stable_sort<_List_iterator
-  <foo,foo &,foo *> >(_List_iterator<foo,foo &,foo *>, 
-  _List_iterator<foo,foo &,foo *>)'
-concept_checks.hpp:209: no match for `_List_iterator<foo,foo &,foo *> &
-  < _List_iterator<foo,foo &,foo *> &'
-
- -This message rectifies several of the shortcomings of the standard -error messages. - -
    -
  • The location of the error, bad_error_eg.cpp:9 is - specified in the error message. -
  • The message refers explicitly to concepts that the user can look - up in the STL documentation ( -RandomAccessIterator). -
  • The error message is now much shorter and does not reveal - internal STL functions. -
  • The presence of concept_checks.hpp and - constraints() in the error message alerts the user to the - fact that the error lies in the user code and not in the library - implementation. -
- - -

Using Concept Checks

- -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. - -
-  template <class T> struct EqualityComparableConcept;
-
- -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 BOOST_CLASS_REQUIRES. -function_requires() function can be used in function bodies -and the BOOST_CLASS_REQUIRES macro 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 BOOST_CLASS_REQUIRES macro can be used inside a class -definition to check whether some type models a concept. - -
-  struct some_class_using_foo {
-    BOOST_CLASS_REQUIRES(foo, EqualityComparableConcept);
-  };
-
- -To add concept checks to the std::stable_sort() function the -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 function_requires() to -check this. - -
-  template <class RandomAccessIter>
-  void stable_sort(RandomAccessIter first, RandomAccessIter last)
-  {
-    function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();
-    typedef typename std::iterator_traits<RandomAccessIter>::value_type value_type;
-    function_requires< LessThanComparableConcept<value_type> >();
-    ...
-  }
-
- - - - - -

-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 -function_requires() is used with the ReadWritePropertyMap -concept which takes two type parameters: a property map and the key -type for the map. - -

-  template <class IncidenceGraph, class Buffer, class BFSVisitor, 
-            class ColorMap>
-  void breadth_first_search(IncidenceGraph& g, 
-    typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
-    Buffer& Q, BFSVisitor vis, ColorMap color)
-  {
-    typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
-    function_requires< ReadWritePropertyMap<ColorMap, Vertex> >();
-    ...
-  }
-
- - -As an example of using 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<AssignableConcept<T> > at the top -of the definition for std::vector. - -
-  namespace std {
-    template <class T>
-    struct vector {
-      typedef typename class_requires< AssignableConcept<T> >::check req;
-      ...
-    };
-  }
-
- - -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 -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: - -
-  #include <boost/concept_checks.hpp>
-
-  #include <iterator>
-  #include <set>
-  #include <map>
-  #include <vector>
-  #include <list>
-  #include <deque>
-
-  int
-  main()
-  {
-    typedef std::vector<int> Vector;
-    typedef std::deque<int> Deque;
-    typedef std::list<int> List;
-
-    function_requires< Mutable_RandomAccessContainer<Vector> >();
-    function_requires< BackInsertionSequence<Vector> >();
-
-    function_requires< Mutable_RandomAccessContainer<Deque> >();
-    function_requires< FrontInsertionSequence<Deque> >();
-    function_requires< BackInsertionSequence<Deque> >();
-
-    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;
-
-    function_requires< SortedAssociativeContainer<Set> >();
-    function_requires< SimpleAssociativeContainer<Set> >();
-    function_requires< UniqueAssociativeContainer<Set> >();
-
-    function_requires< SortedAssociativeContainer<MultiSet> >();
-    function_requires< SimpleAssociativeContainer<MultiSet> >();
-    function_requires< MultipleAssociativeContainer<MultiSet> >();
-
-    function_requires< SortedAssociativeContainer<Map> >();
-    function_requires< UniqueAssociativeContainer<Map> >();
-    function_requires< PairAssociativeContainer<Map> >();
-
-    function_requires< SortedAssociativeContainer<MultiMap> >();
-    function_requires< MultipleAssociativeContainer<MultiMap> >();
-    function_requires< PairAssociativeContainer<MultiMap> >();
-
-    return 0;
-  }
-
- - -

Creating Concept Checking Classes

- -As an example of how to create a concept checking class, we look -at how to create the corresponding checks for the - -RandomAccessIterator concept. First, as a convention we name the -concept checking class after the concept, and add the suffix -``_concept''. Note that the REQUIRE macro expects -the suffix to be there. Next we must define a member function named -constraints() in which we will exercise the valid expressions -of the concept. The REQUIRE macro expects this function's -signature to appear exactly as it is appears below: a void -non-const member function with no parameters. - -

-The first part of the constraints() function includes -the requirements that correspond to the refinement relationship -between -RandomAccessIterator and the concepts which it builds upon: - -BidirectionalIterator and - -LessThanComparable. We could have instead used -CLASS_REQUIRES and placed these requirements in the class -body, however CLASS_REQUIRES uses C++ language features that -are less portable. - -

-Next we check that the iterator_category of the iterator is -either std::random_access_iterator_tag or a derived class. -After that we write out some code that corresponds to the valid -expressions of the -RandomAccessIterator concept. Typedefs can also be added to -enforce the associated types of the concept. - -

-  template <class Iter>
-  struct RandomAccessIterator_concept
-  {
-    void constraints() {
-      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;
-      i -= n;
-      i = i - n;
-      n = i - j;
-      i[n];
-    }
-    Iter a, b;
-    Iter i, j;
-    typename std::iterator_traits<Iter>::difference_type n;
-  };
-}
-
- -One potential pitfall in designing concept checking classes is using -more expressions in the constraint function than necessary. For -example, it is easy to accidentally use the default constructor to -create the objects that will be needed in the expressions (and not all -concepts require a default constructor). This is the reason we write -the constraint function as a member function of a class. The objects -involved in the expressions are declared as data members of the class. -Since objects of the constraints class template are never -instantiated, the default constructor for the concept checking class -is never instantiated. Hence the data member's default constructors -are never instantiated (C++ Standard Section 14.7.1 9). - - -

Concept Covering and Archetypes

- -We have discussed how it is important to select the minimal -requirements (concepts) for the inputs to a component, but it is -equally important to verify that the chosen concepts cover the -algorithm. That is, any possible user error should be caught by the -concept checks and not let slip through. Concept coverage can be -verified through the use of archetype classes. An archetype -class is an exact implementation of the interface associated with a -particular concept. The run-time behavior of the archetype class is -not important, the functions can be left empty. A simple test program -can then be compiled with the archetype classes as the inputs to the -component. If the program compiles then one can be sure that the -concepts cover the component. - -The following code shows the archetype class for the TrivialIterator -concept. Some care must be taken to ensure that the archetype is an -exact match to the concept. For example, the concept states that the -return type of operator*() must be convertible to the value -type. It does not state the more stringent requirement that the return -type be T& or const T&. That means it would be a -mistake to use T& or const T& for the return type -of the archetype class. The correct approach is to create an -artificial return type that is convertible to T, as we have -done here with input_proxy. The validity of the archetype -class test is completely dependent on it being an exact match with the -concept, which must be verified by careful (manual) inspection. - -
-  template <class T>
-  struct input_proxy {
-    operator T() { return t; }
-    static T t;
-  };
-  template <class T>
-  class trivial_iterator_archetype
-  {
-    typedef trivial_iterator_archetype self;
-  public:
-    trivial_iterator_archetype() { }
-    trivial_iterator_archetype(const self&) { }
-    self& operator=(const self&) { return *this;  }
-    friend bool operator==(const self&, const self&) { return true; }
-    friend bool operator!=(const self&, const self&) { return true; }
-    input_proxy<T> operator*() { return input_proxy<T>(); }
-  };
-
-  namespace std {
-    template <class T>
-    struct iterator_traits< trivial_iterator_archetype<T> >
-    {
-      typedef T value_type;
-    };
-  }
-
- -Generic algorithms are often tested by being instantiated with a -number of common input types. For example, one might apply -std::stable_sort() with basic pointer types as the iterators. -Though appropriate for testing the run-time behavior of the algorithm, -this is not helpful for ensuring concept coverage because C++ types -never match particular concepts, they often provide much more than the -minimal functionality required by any one concept. That is, even -though the function template compiles with a given type, the concept -requirements may still fall short of covering the functions actual -requirements. This is why it is important to compile with archetype -classes in addition to testing with common input types. - -

-The following is an excerpt from stl_concept_covering.cpp -that shows how archetypes can be used to check the requirement -documentation for - -std::stable_sort(). In this case, it looks like the CopyConstructible and Assignable requirements were -forgotten in the SGI STL documentation (try removing those -archetypes). The Boost archetype classes have been designed so that -they can be layered. In this example the value type of the iterator -is composed out of three archetypes. In the archetype class reference -below, template parameters named Base indicate where the -layered archetype can be used. - -

-  {
-    typedef less_than_comparable_archetype< 
-      copy_constructible_archetype<
-        assignable_archetype<> > > ValueType;
-    random_access_iterator_archetype<ValueType> ri;
-    std::stable_sort(ri, ri);
-  }
-
- - -

Programming with Concepts

- -The process of deciding how to group requirements into concepts and -deciding which concepts to use in each algorithm is perhaps the most -difficult (yet most important) part of building a generic library. -A guiding principle to use during this process is one we -call the requirement minimization principle. - -

-Requirement Minimization Principle: Minimize the requirements -on the input parameters of a component to increase its reusability. - -

-There is natural tension in this statement. By definition, the input -parameters must be used by the component in order for the component to -accomplish its task (by ``component'' we mean a function or class -template). The challenge then is to implement the component in such a -way that makes the fewest assumptions (the minimum requirements) about -the inputs while still accomplishing the task. - -

-The traditional notions of abstraction tie in directly to the -idea of minimal requirements. The more abstract the input, the fewer -the requirements. Thus, concepts are simply the embodiment of generic -abstract data types in C++ template programming. - -

-When designing the concepts for some problem domain it is important to -keep in mind their purpose, namely to express the requirements for the -input to the components. With respect to the requirement minimization -principle, this means we want to minimize concepts. - -

-It is important to note, however, that -minimizing concepts does not mean simply -reducing the number of valid expressions -in the concept. -For example, the -std::stable_sort() function requires that the value type of -the iterator be -LessThanComparable, which not only -includes operator<(), but also operator>(), -operator<=(), and operator>=(). -It turns out that std::stable_sort() only uses -operator<(). The question then arises: should -std::stable_sort() be specified in terms of the concept - -LessThanComparable or in terms of a concept that only -requires operator<()? - -

-We remark first that the use of -LessThanComparable does not really violate the requirement -minimization principle because all of the other operators can be -trivially implemented in terms of operator<(). By -``trivial'' we mean one line of code and a constant run-time cost. -More fundamentally, however, the use of -LessThanComparable does not violate the requirement minimization -principle because all of the comparison operators (<, ->, <=, >=) are conceptually equivalent (in -a mathematical sense). Adding conceptually equivalent valid -expressions is not a violation of the requirement minimization -principle because no new semantics are being added --- only new -syntax. The added syntax increases re-usability. - -

-For example, -the -maintainer of the std::stable_sort() may some day change the -implementation in places to use operator>() instead of -operator<(), since, after all, they are equivalent. Since the -requirements are part of the public interface, such a change could -potentially break client code. If instead - -LessThanComparable is given as the requirement for -std::stable_sort(), then the maintainer is given a reasonable -amount of flexibility within which to work. - -

-Minimality in concepts is a property associated with the underlying -semantics of the problem domain being represented. In the problem -domain of basic containers, requiring traversal in a single direction -is a smaller requirement than requiring traversal in both directions -(hence the distinction between -ForwardIterator and - -BidirectionalIterator). The semantic difference can be easily seen -in the difference between the set of concrete data structures that -have forward iterators versus the set that has bidirectional -iterators. For example, singly-linked lists would fall in the set of -data structures having forward iterators, but not bidirectional -iterators. In addition, the set of algorithms that one can implement -using only forward iterators is quite different than the set that can -be implemented with bidirectional iterators. Because of this, it is -important to factor families of requirements into rather fine-grained -concepts. For example, the requirements for iterators are factored -into the six STL iterator concepts (trivial, output, input, forward, -bidirectional, and random access). - - -

Implementation

- -Ideally we would like to catch, and indicate, the concept violation at -the point of instantiation. As mentioned in D&E[2], the error -can be caught by exercising all of the requirements needed by the -function template. Exactly how the requirements (the valid -expressions in particular) are exercised is a tricky issue, since we -want the code to be compiled --- but not executed. Our -approach is to exercise the requirements in a separate function that -is assigned to a function pointer. In this case, the compiler will -instantiate the function but will not actually invoke it. In -addition, an optimizing compiler will remove the pointer assignment as -``dead code'' (though the run-time overhead added by the assignment -would be trivial in any case). It might be conceivable for a compiler -to skip the semantic analysis and compilation of the constraints -function in the first place, which would make our function pointer -technique ineffective. However, this is unlikely because removal of -unnecessary code and functions is typically done in later stages of a -compiler. We have successfully used the function pointer technique -with GNU C++, Microsoft Visual C++, and several EDG-based compilers -(KAI C++, SGI MIPSpro). The following code shows how this technique -can be applied to the std::stable_sort() function: - -
-  template <class RandomAccessIterator>
-  void stable_sort_constraints(RandomAccessIterator i) {
-    typename std::iterator_traits<RandomAccessIterator>
-      ::difference_type n;
-    i += n;  // exercise the requirements for RandomAccessIterator
-    ...
-  }
-  template <class RandomAccessIterator>
-  void stable_sort(RandomAccessIterator first, RandomAccessIterator last) {
-    typedef void (*fptr_type)(RandomAccessIterator);
-    fptr_type x = &stable_sort_constraints;
-    ...
-  }
-
- -There is often a large set of requirements that need to be checked, -and it would be cumbersome for the library implementor to write -constraint functions like stable_sort_constraints() for every -public function. Instead, we group sets of valid expressions -together, according to the definitions of the corresponding concepts. -For each concept we define a concept checking class template where the -template parameter is for the type to be checked. The class contains -a contraints() member function which exercises all of the -valid expressions of the concept. The objects used in the constraints -function, such as n and i, are declared as data -members of the concept checking class. - -
-  template <class Iter>
-  struct RandomAccessIterator_concept {
-    void constraints() {
-      i += n;
-      ...
-    }
-    typename std::iterator_traits<RandomAccessIterator>
-      ::difference_type n;
-    Iter i;
-    ...
-  };
-
- -We can still use the function pointer mechanism to cause instantiation -of the constraints function, however now it will be a member function -pointer. To make it easy for the library implementor to invoke the -concept checks, we wrap the member function pointer mechanism in a -function named function_requires(). The following code -snippet shows how to use function_requires() to make sure -that the iterator is a - -RandomAccessIterator. - -
-  template <class RandomAccessIter>
-  void stable_sort(RandomAccessIter first, RandomAccessIter last)
-  {
-    function_requires< RandomAccessIteratorConcept >();
-    ...
-  }
-
- -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. - -
-  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 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. - -
-  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;
-  };
-
- -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

- - -

Functions

- -
-  template <class Concept>
-  void function_requires();
-
- -

Classes

-
-  template <class Concept>
-  struct class_requires {
-    typedef ... check;
-  };
-
- -
-  // 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 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 LeftEqualityComparableConcept;
-  template <class T> struct LessThanComparableConcept;
-
- -

Iterator Concept Checking Classes

- -
-  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 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 ContainerConcept;
-  template <class C> struct Mutable_ContainerConcept;
-
-  template <class C> struct ForwardContainerConcept;
-  template <class C> struct Mutable_ForwardContainerConcept;
-
-  template <class C> struct ReversibleContainerConcept;
-  template <class C> struct Mutable_ReversibleContainerConcept;
-
-  template <class C> struct RandomAccessContainerConcept;
-  template <class C> struct Mutable_RandomAccessContainerConcept;
-
-  template <class C> struct SequenceConcept;
-  template <class C> struct FrontInsertionSequenceConcept;
-  template <class C> struct BackInsertionSequenceConcept;
-
-  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;
-
- - -

Basic Archetype Classes

- -
-  class null_archetype; // A type that models no concepts.
-  template <class Base = null_archetype> class default_constructible_archetype;
-  template <class Base = null_archetype> class assignable_archetype;
-  template <class Base = null_archetype> class copy_constructible_archetype;
-  template <class Left, class Base = null_archetype> class left_equality_comparable_archetype;
-  template <class Base = null_archetype> class equality_comparable_archetype;
-  template <class T, class Base = null_archetype> class convertible_to_archetype;
-
- -

Iterator Archetype Classes

- -
-  template <class ValueType> class trivial_iterator_archetype;
-  template <class ValueType> class mutable_trivial_iterator_archetype;
-  template <class ValueType> class input_iterator_archetype;
-  template <class ValueType> class forward_iterator_archetype;
-  template <class ValueType> class bidirectional_iterator_archetype;
-  template <class ValueType> class random_access_iterator_archetype;
-
- -

Function Object Archetype Classes

- -
-  template <class Arg, class Return> class unary_function_archetype;
-  template <class Arg1, class Arg2, class Return> class binary_function_archetype;
-  template <class Arg> class predicate_archetype;
-  template <class Arg1, class Arg2> class binary_predicate_archetype;
-
- -

Container Archetype Classes

- -
-UNDER CONSTRUCTION
-
- -

History

- -An earlier version of this concept checking system was developed by -the author while working at SGI in their C++ compiler and library -group. The earlier version is now part of the SGI STL distribution. The -boost concept checking library differs from the concept checking in -the SGI STL in that the definition of concept checking classes has -been greatly simplified, at the price of less helpful verbiage in the -error messages. - -

Publications

- - - -

Acknowledgements

- -The idea to use function pointers to cause instantiation is due to -Alexander Stepanov. I am not sure of the origin of the idea to use -expressions to do up-front checking of templates, but it did appear in -D&E[ -2]. -Thanks to Matt Austern for his excellent documentation and -organization of the STL concepts, upon which these concept checks -are based. Thanks to Boost members for helpful comments and -reviews. - -
-
- - -
Copyright © 2000 -Jeremy Siek, -Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/concept_checks_fail_expected.cpp b/concept_checks_fail_expected.cpp deleted file mode 100644 index a646746..0000000 --- a/concept_checks_fail_expected.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// (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 - -/* - - This file verifies that function_requires() of the Boost Concept - Checking Library catches errors when it is suppose to. - -*/ - -struct foo { }; - -int -main() -{ - boost::function_requires< boost::EqualityComparableConcept >(); - return 0; -} diff --git a/concept_checks_test.cpp b/concept_checks_test.cpp deleted file mode 100644 index b5fc58b..0000000 --- a/concept_checks_test.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// (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 -#include - -/* - - 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; - - //=========================================================================== - // Basic Concepts - { - typedef default_constructible_archetype<> foo; - function_requires< DefaultConstructibleConcept >(); - } - { - typedef assignable_archetype<> foo; - function_requires< AssignableConcept >(); - } - { - typedef copy_constructible_archetype<> foo; - function_requires< CopyConstructibleConcept >(); - } - { - typedef sgi_assignable_archetype<> foo; - function_requires< SGIAssignableConcept >(); - } - { - typedef copy_constructible_archetype<> foo; - typedef convertible_to_archetype convertible_to_foo; - function_requires< ConvertibleConcept >(); - } - { - function_requires< ConvertibleConcept >(); - } - { - typedef equality_comparable_archetype<> foo; - function_requires< EqualityComparableConcept >(); - } - { - typedef less_than_comparable_archetype<> foo; - function_requires< LessThanComparableConcept >(); - } - { - typedef comparable_archetype<> foo; - function_requires< ComparableConcept >(); - } - { - typedef equal_op_first_archetype<> First; - typedef equal_op_second_archetype<> Second; - function_requires< EqualOpConcept >(); - } - { - typedef not_equal_op_first_archetype<> First; - typedef not_equal_op_second_archetype<> Second; - function_requires< NotEqualOpConcept >(); - } - { - typedef less_than_op_first_archetype<> First; - typedef less_than_op_second_archetype<> Second; - function_requires< LessThanOpConcept >(); - } - { - typedef less_equal_op_first_archetype<> First; - typedef less_equal_op_second_archetype<> Second; - function_requires< LessEqualOpConcept >(); - } - { - typedef greater_than_op_first_archetype<> First; - typedef greater_than_op_second_archetype<> Second; - function_requires< GreaterThanOpConcept >(); - } - { - typedef greater_equal_op_first_archetype<> First; - typedef greater_equal_op_second_archetype<> Second; - function_requires< GreaterEqualOpConcept >(); - } - - { - typedef copy_constructible_archetype<> Return; - typedef plus_op_first_archetype First; - typedef plus_op_second_archetype Second; - function_requires< PlusOpConcept >(); - } - - //=========================================================================== - // Function Object Concepts - - { - typedef generator_archetype > foo; - function_requires< GeneratorConcept > >(); - } - { - function_requires< GeneratorConcept< void_generator_archetype, void > >(); - } - { - typedef unary_function_archetype F; - function_requires< UnaryFunctionConcept >(); - } - { - typedef binary_function_archetype F; - function_requires< BinaryFunctionConcept >(); - } - { - typedef unary_predicate_archetype F; - function_requires< UnaryPredicateConcept >(); - } - { - typedef binary_predicate_archetype F; - function_requires< BinaryPredicateConcept >(); - typedef const_binary_predicate_archetype const_F; - function_requires< Const_BinaryPredicateConcept >(); - } - - //=========================================================================== - // Iterator Concepts - { - typedef trivial_iterator_archetype > Iter; - function_requires< TrivialIteratorConcept >(); - } - { - typedef mutable_trivial_iterator_archetype > Iter; - function_requires< Mutable_TrivialIteratorConcept >(); - } - { - typedef input_iterator_archetype > Iter; - function_requires< InputIteratorConcept >(); - } - { - typedef output_iterator_archetype Iter; - function_requires< OutputIteratorConcept >(); - } - { - typedef forward_iterator_archetype > Iter; - function_requires< ForwardIteratorConcept >(); - } - { - typedef forward_iterator_archetype > Iter; - function_requires< Mutable_ForwardIteratorConcept >(); - } - { - typedef bidirectional_iterator_archetype > Iter; - function_requires< BidirectionalIteratorConcept >(); - } - { - typedef bidirectional_iterator_archetype > Iter; - function_requires< Mutable_BidirectionalIteratorConcept >(); - } - { - typedef random_access_iterator_archetype > Iter; - function_requires< RandomAccessIteratorConcept >(); - } - { - typedef random_access_iterator_archetype > Iter; - function_requires< Mutable_RandomAccessIteratorConcept >(); - } - - //=========================================================================== - // Container Concepts - - { - - function_requires< ContainerConcept< > >(); - } - { - - } - - return 0; -} diff --git a/stl_concept_checks.cpp b/stl_concept_checks.cpp deleted file mode 100644 index 0bcfad2..0000000 --- a/stl_concept_checks.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// (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. - -// -// 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 - -#include -#include -#include -#include -#include -#include -#ifndef BOOST_NO_SLIST -#include -#endif - -//#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 -#else - typedef std::vector Vector; - typedef std::deque Deque; - typedef std::list List; - - // VC++ missing pointer and const_pointer typedefs - 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 - function_requires< Mutable_RandomAccessContainerConcept >(); -#endif - // warnings about signed and unsigned in old deque version - function_requires< FrontInsertionSequenceConcept >(); - function_requires< BackInsertionSequenceConcept >(); -#endif - - // VC++ missing pointer and const_pointer typedefs - function_requires< Mutable_ReversibleContainerConcept >(); - function_requires< FrontInsertionSequenceConcept >(); - function_requires< BackInsertionSequenceConcept >(); - -#ifndef BOOST_NO_SLIST - typedef std::slist SList; - function_requires< FrontInsertionSequenceConcept >(); -#endif - - typedef std::set Set; - typedef std::multiset MultiSet; - typedef std::map Map; - typedef std::multimap MultiMap; - - function_requires< SortedAssociativeContainerConcept >(); - function_requires< SimpleAssociativeContainerConcept >(); - function_requires< UniqueAssociativeContainerConcept >(); - - function_requires< SortedAssociativeContainerConcept >(); - function_requires< SimpleAssociativeContainerConcept >(); - function_requires< MultipleAssociativeContainerConcept >(); - - function_requires< SortedAssociativeContainerConcept >(); - function_requires< UniqueAssociativeContainerConcept >(); - function_requires< PairAssociativeContainerConcept >(); - - function_requires< SortedAssociativeContainerConcept >(); - function_requires< MultipleAssociativeContainerConcept >(); - function_requires< PairAssociativeContainerConcept >(); -#endif - - return 0; -} diff --git a/stl_concept_checks.expected b/stl_concept_checks.expected deleted file mode 100644 index e69de29..0000000 From 949c2b1b28a14e23db4a7d8604b26b87ceaaf1b5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 11 Sep 2006 22:27:29 +0000 Subject: [PATCH 02/31] Add missing license/copyright [SVN r35070] --- Jamfile | 3 +++ Jamfile.v2 | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Jamfile b/Jamfile index 7cd68ec..8b7c473 100644 --- a/Jamfile +++ b/Jamfile @@ -1,3 +1,6 @@ +# Copyright David Abrahams, Jeremy Siek 2006. Distributed under the +# Boost Software License, Version 1.0. (See accompanying file +# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) subproject libs/concept_check ; import testing ; diff --git a/Jamfile.v2 b/Jamfile.v2 index 84bbb6d..fb7b31a 100644 --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -1,4 +1,7 @@ - +# Copyright David Abrahams, Jeremy Siek, Vladimir Prus +# 2006. Distributed under the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) import testing ; test-suite concept_check From a88c1d6a6994cac8e02bc617602455a805a16b24 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Mon, 6 Nov 2006 17:10:46 +0000 Subject: [PATCH 03/31] Remove obsolete Boost.Build v1 files. [SVN r35880] --- Jamfile | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 Jamfile diff --git a/Jamfile b/Jamfile deleted file mode 100644 index 8b7c473..0000000 --- a/Jamfile +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright David Abrahams, Jeremy Siek 2006. Distributed under the -# Boost Software License, Version 1.0. (See accompanying file -# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -subproject libs/concept_check ; - -import testing ; - -test-suite concept_check - : [ compile stl_concept_covering.cpp ] - [ compile concept_check_test.cpp ] - [ compile class_concept_check_test.cpp ] - [ link-fail concept_check_fail_expected.cpp ] - [ link-fail class_concept_fail_expected.cpp ] - ; From cf9b413943147faeab642a83b01b05402cdbfad8 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 7 Nov 2006 19:27:00 +0000 Subject: [PATCH 04/31] Merged copyright and license addition [SVN r35907] --- index.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index cc13c7a..36fea49 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,10 @@ Automatic redirection failed, please go to -concept_check.htm. +concept_check.htm
+

Copyright Beman Dawes, 2001

+

Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy +at www.boost.org/LICENSE_1_0.txt)

\ No newline at end of file From bee3ccbb6c20eb1930ccc13a447c3fe642906291 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Tue, 28 Nov 2006 17:28:34 +0000 Subject: [PATCH 05/31] Change tests to run and compile-fail. [SVN r36196] --- Jamfile.v2 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Jamfile.v2 b/Jamfile.v2 index fb7b31a..7b3a802 100644 --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -5,9 +5,9 @@ import testing ; test-suite concept_check - : [ compile stl_concept_covering.cpp ] - [ compile concept_check_test.cpp ] - [ compile class_concept_check_test.cpp ] - [ link-fail concept_check_fail_expected.cpp ] - [ link-fail class_concept_fail_expected.cpp ] + : [ run stl_concept_covering.cpp ] + [ run concept_check_test.cpp ] + [ run class_concept_check_test.cpp ] + [ compile-fail concept_check_fail_expected.cpp ] + [ compile-fail class_concept_fail_expected.cpp ] ; From d0c4fe7914c3da8e14c97c709c8a53f00bc6a702 Mon Sep 17 00:00:00 2001 From: Thomas Witt Date: Fri, 1 Jun 2007 16:12:08 +0000 Subject: [PATCH 06/31] Patches from Trac #583. [SVN r37846] --- stl_concept_covering.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl_concept_covering.cpp b/stl_concept_covering.cpp index 5b05beb..3d60a80 100644 --- a/stl_concept_covering.cpp +++ b/stl_concept_covering.cpp @@ -591,7 +591,7 @@ main() std::nth_element(ri, ri, ri, comp); } { -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__IBMCPP__) typedef less_than_op_first_archetype<> FT; typedef less_than_op_second_archetype<> T; #elif defined(__KCC) @@ -615,7 +615,7 @@ main() fi = std::lower_bound(fi, fi, value, comp); } { -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__IBMCPP__) // Note, order of T,FT is flipped from lower_bound typedef less_than_op_second_archetype<> FT; typedef less_than_op_first_archetype<> T; @@ -639,7 +639,7 @@ main() fi = std::upper_bound(fi, fi, value, comp); } { -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__IBMCPP__) typedef less_than_op_first_archetype< less_than_op_second_archetype< null_archetype<>, optag2>, optag1> FT; typedef less_than_op_second_archetype< @@ -669,7 +669,7 @@ main() ignore_unused_variable_warning(p); } { -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__IBMCPP__) typedef less_than_op_first_archetype< less_than_op_second_archetype, optag2>, optag1> FT; typedef less_than_op_second_archetype< @@ -686,7 +686,7 @@ main() { typedef null_archetype Arg1; typedef null_archetype Arg2; -#if defined(__GNUC__) || defined(__KCC) +#if defined(__GNUC__) || defined(__KCC) || defined(__IBMCPP__) typedef convertible_to_archetype > FT; typedef convertible_to_archetype Tout; -#if defined(__GNUC__) || defined(__KCC) +#if defined(__GNUC__) || defined(__KCC) || defined(__IBMCPP__) typedef less_than_op_first_archetype< less_than_op_second_archetype< convertible_to_archetype, optag2>, optag1 > Tin1; From fe5e093f53be6c344e03b1a57f441d1979a05432 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 24 Jul 2007 19:28:14 +0000 Subject: [PATCH 07/31] This commit was manufactured by cvs2svn to create tag 'Version_1_34_1'. [SVN r38286] From 96d6053a524c60ea8a909293c7a26ded0a3f21bd Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Fri, 5 Oct 2007 14:25:06 +0000 Subject: [PATCH 08/31] Starting point for releases [SVN r39706] From 997b34b581292641b851c467c35370c0f643e4ab Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sun, 25 Nov 2007 18:38:02 +0000 Subject: [PATCH 09/31] Full merge from trunk at revision 41356 of entire boost-root tree. [SVN r41370] --- Jamfile.v2 | 12 + bad_error_eg.cpp | 19 +- bibliography.htm | 17 +- class_concept_check_test.cpp | 16 +- class_concept_fail_expected.cpp | 13 +- concept_check.htm | 537 +++++++++++++++--------------- concept_check_fail_expected.cpp | 10 +- concept_check_test.cpp | 64 ++-- concept_covering.htm | 225 +++++++------ creating_concepts.htm | 237 +++++++------ fake_sort.hpp | 27 ++ function_requires_fail.cpp | 26 ++ implementation.htm | 225 ++++++------- old_concept_class_fail.cpp | 28 ++ old_concept_function_fail.cpp | 23 ++ old_concept_pass.cpp | 34 ++ old_concepts.hpp | 67 ++++ prog_with_concepts.htm | 164 +++++---- reference.htm | 572 +++++++++++++++++++------------- stl_concept_check.cpp | 46 +-- stl_concept_covering.cpp | 14 +- usage_fail.cpp | 22 ++ using_concept_check.htm | 359 +++++++++----------- where.cpp | 13 + where_fail.cpp | 13 + 25 files changed, 1581 insertions(+), 1202 deletions(-) create mode 100755 fake_sort.hpp create mode 100755 function_requires_fail.cpp create mode 100755 old_concept_class_fail.cpp create mode 100755 old_concept_function_fail.cpp create mode 100755 old_concept_pass.cpp create mode 100755 old_concepts.hpp create mode 100755 usage_fail.cpp create mode 100755 where.cpp create mode 100755 where_fail.cpp diff --git a/Jamfile.v2 b/Jamfile.v2 index 7b3a802..7b7c833 100644 --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -6,8 +6,20 @@ import testing ; test-suite concept_check : [ run stl_concept_covering.cpp ] + [ run stl_concept_check.cpp ] [ run concept_check_test.cpp ] [ run class_concept_check_test.cpp ] [ compile-fail concept_check_fail_expected.cpp ] [ compile-fail class_concept_fail_expected.cpp ] + + [ run where.cpp ] + [ compile-fail where_fail.cpp ] + [ compile-fail usage_fail.cpp ] + + # Backward compatibility tests + [ run old_concept_pass.cpp ] + [ compile-fail function_requires_fail.cpp ] + [ compile-fail old_concept_function_fail.cpp ] + [ compile-fail old_concept_class_fail.cpp ] ; + diff --git a/bad_error_eg.cpp b/bad_error_eg.cpp index 644ac4c..5f8d892 100644 --- a/bad_error_eg.cpp +++ b/bad_error_eg.cpp @@ -1,13 +1,14 @@ +#include +#include +#include "algorithm" + +int main() +{ + std::vector > v; + std_::stable_sort(v.begin(), v.end()); +} + // (C) Copyright Jeremy Siek 2000. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) - -#include -#include - -int main() { - std::list v; - std::stable_sort(v.begin(), v.end()); - return 0; -} diff --git a/bibliography.htm b/bibliography.htm index 267f6c1..2c42925 100644 --- a/bibliography.htm +++ b/bibliography.htm @@ -1,17 +1,10 @@ - + + + + -Boost Graph Library: Bibliography +Boost Concept Checking Library: Bibliography )); + typedef int* int_ptr; typedef const int* const_int_ptr; + BOOST_CONCEPT_ASSERT((boost::EqualOp)); + BOOST_CONCEPT_ASSERT((boost::UnaryFunction)); + BOOST_CONCEPT_ASSERT((boost::BinaryFunction)); }; int main() { - class_requires_test x; - boost::ignore_unused_variable_warning(x); - return 0; + class_requires_test x; + boost::ignore_unused_variable_warning(x); + return 0; } diff --git a/class_concept_fail_expected.cpp b/class_concept_fail_expected.cpp index 11f7f52..74268e3 100644 --- a/class_concept_fail_expected.cpp +++ b/class_concept_fail_expected.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2000. +// (C) Copyright Jeremy Siek, David Abrahams 2000-2006. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,21 +11,22 @@ /* This file verifies that class_requires of the Boost Concept Checking - Library catches errors when it is suppose to. + Library catches errors when it is supposed to. */ struct foo { }; +template class class_requires_test { - BOOST_CLASS_REQUIRE(foo, boost, EqualityComparableConcept); + BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); }; int main() { - class_requires_test x; - (void)x; // suppress unused variable warning - return 0; + class_requires_test x; + (void)x; // suppress unused variable warning + return 0; } diff --git a/concept_check.htm b/concept_check.htm index 0e55aa8..0f70167 100644 --- a/concept_check.htm +++ b/concept_check.htm @@ -1,313 +1,330 @@ - - - -Concept Check Library + + + + + + + + + + + + + Concept Check Library + - -C++ Boost + + C++ Boost
-
+

The Boost Concept Check Library (BCCL)

-

The Boost Concept Check Library (BCCL)

+
+ The Concept Check library allows one to add explicit statement and + checking of concepts in the style + of the proposed + C++ language extension. +
-

- -header -boost/concept_check.hpp -
and -boost/concept_archetype.hpp -

+

Synopsis

-

-Generic programming in C++ is characterized by the use of template -parameters to represent abstract data types (or ``concepts''). -However, the C++ language itself does not provide a mechanism for the -writer of a class or function template to explicitly state what -concept the user-supplied template argument should model (or conform -to). The common practice is to name the template parameter after the -required concept as a hint to the user and to state the concept -requirements in the documentation. However, often times the -requirements are vague, incorrect, or nonexistent, which is quite a -problem for the user, since he or she will not know exactly what kind -of input is expected by the template. Furthermore, the following -problems occur: +

Generic programming in C++ is characterized by the use of template + parameters to represent abstract data types (or “concepts”). However, the + C++ language itself does not provide a mechanism for the writer of a class + or function template to explicitly state the concept that the user-supplied + template argument should model (or conform to). Template parameters are + commonly named after the concept they're required to model as a hint to the + user, and to make the concept requirements explicit in code. However, the + compiler doesn't treat these special names specially: a parameter named + RandomAccessIterator is no different to the compiler than one + named T. Furthermore,

-
    -
  • Compiler error messages resulting from incorrect template - arguments can be particularly difficult to decipher. Often times - the error does not point to the location of the template - call-site, but instead exposes the internals of the template, which - the user should never have to see.
  • +
      +
    • Compiler error messages resulting from incorrect template arguments + can be particularly difficult to decipher. Often times the error does not + point to the location of the template call-site, but instead exposes the + internals of the template, which the user should never have to see.
    • -
    • The documented concept requirements may not fully cover - the template, meaning the user could get a compiler error even - though the supplied template arguments meet the documented - requirements.
    • +
    • Without checking from the compiler, the documented requirements are + oftentimes vague, incorrect, or nonexistent, so a user cannot know + exactly what kind of arguments are expected.
    • -
    • The documented concept requirements may be too stringent, - requiring more than is really needed by the template.
    • +
    • The documented concept requirements may not fully cover the + needs of the actual template, meaning the user could get a compiler error + even though the supplied template arguments meet the documented + requirements.
    • -
    • The requirements are not explicitly stated in the code, which - makes the code harder to understand. Also, the code may - get out-of-sync with the documented requirements.
    • -
    +
  • The documented concept requirements may be too stringent, requiring + more than is really needed by the template.
  • -The Boost Concept Checking Library provides: +
  • Concept names in code may drift out-of-sync with the documented + requirements.
  • +

The Boost Concept Checking Library provides: -

    -
  • A mechanism for inserting compile-time checks of template - parameters.
  • +
      +
    • A mechanism for inserting compile-time checks on template parameters + at their point of use.
    • -
    • A framework for specifying concept requirements though concept - checking classes.
    • +
    • A framework for specifying concept requirements though concept + checking classes.
    • -
    • A mechanism for verifying that concept requirements cover the template.
    • +
    • A mechanism for verifying that concept requirements cover the + template.
    • -
    • A suite of concept checking classes and archetype classes that - match the concept requirements in the C++ Standard Library.
    • -
    +
  • A suite of concept checking classes and archetype classes that match + the concept requirements in the C++ Standard Library.
  • -The mechanisms use standard C++ and introduce no run-time -overhead. The main cost of using the mechanism is in compile-time. +
  • An alternative to the use of traits classes for accessing associated + types that mirrors the syntax proposed for the next C++ standard.
  • +

The mechanisms use standard C++ and introduce no run-time overhead. + The main cost of using the mechanism is in compile-time.

-

-Any programmer writing class or function templates ought to make -concept checking a normal part of their code writing routine. A -concept check should be inserted for each template parameter in a -component's public interface. If the concept is one of the ones from -the Standard Library, then simply use the matching concept checking -class in the BCCL. If not, then write a new concept checking class - -after all, they are typically only a few lines long. For new concepts, -a matching archetype class should also be created, which is a minimal -skeleton-implementation of the concept +

Every programmer writing class or function templates ought to + make concept checking a normal part of their code writing routine. + A concept check should be inserted for each template parameter in a + component's public interface. If the concept is one of the ones from the + Standard Library, then simply use the matching concept checking class in + the BCCL. If not, then write a new concept checking class - after all, they + are typically only a few lines long. For new concepts, a matching archetype + class should also be created, which is a minimal skeleton-implementation of + the concept

-

-The documentation is organized into the following sections. +

The documentation is organized into the following sections.

-
    -
  1. Introduction
  2. -
  3. Motivating Example
  4. -
  5. History
  6. -
  7. Publications
  8. -
  9. Acknowledgements
  10. -
  11. Using Concept Checks
  12. -
  13. Creating Concept Checking Classes
  14. -
  15. Concept Covering and Archetypes
  16. -
  17. Programming With Concepts
  18. -
  19. Implementation
  20. -
  21. Reference
  22. -
+
    +
  1. Introduction
  2. -

    -Jeremy Siek contributed -this library. Beman Dawes -managed the formal review. +

  3. Motivating Example
  4. -

    Introduction

    - -A concept is a set of requirements (valid expressions, -associated types, semantic invariants, complexity guarantees, etc.) -that a type must fulfill to be correctly used as arguments in a call -to a generic algorithm. In C++, concepts are represented by formal -template parameters to function templates (generic algorithms). -However, C++ has no explicit mechanism for representing concepts --- -template parameters are merely placeholders. By convention, these -parameters are given names corresponding to the concept that is -required, but a C++ compiler does not enforce compliance to the -concept when the template parameter is bound to an actual type. +
  5. History
  6. -

    -Naturally, if a generic algorithm is invoked with a type that does not -fulfill at least the syntactic requirements of the concept, a -compile-time error will occur. However, this error will not per - se reflect the fact that the type did not meet all of the -requirements of the concept. Rather, the error may occur deep inside -the instantiation hierarchy at the point where an expression is not -valid for the type, or where a presumed associated type is not -available. The resulting error messages are largely uninformative and -basically impenetrable. +

  7. Publications
  8. -

    -What is required is a mechanism for enforcing ``concept safety'' at -(or close to) the point of instantiation. The Boost Concept Checking -Library uses some standard C++ constructs to enforce early concept -compliance and that provides more informative error messages upon -non-compliance. +

  9. Acknowledgements
  10. -

    -Note that this technique only addresses the syntactic -requirements of concepts (the valid expressions and associated types). -We do not address the semantic invariants or complexity guarantees, -which are also part of concept requirements.. +

  11. Using Concept Checks
  12. -

    Motivating Example

    +
  13. Creating Concept Checking + Classes
  14. -We present a simple example to illustrate incorrect usage of a -template library and the resulting error messages. In the code below, -the generic std::stable_sort() algorithm from the Standard -Template Library (STL)[3, 4,5] is applied to -a linked list. +
  15. Concept Covering and + Archetypes
  16. -
    +    
  17. Programming With Concepts
  18. + +
  19. Implementation
  20. + +
  21. Reference
  22. +
+ +

Jeremy Siek contributed this + library. Beman Dawes managed + the formal review. Dave + Abrahams contributed a rewrite that updated syntax to be more + compatible with proposed syntax for concept support the C++ core + language.

+ +

Introduction

A + concept is a set of requirements (valid expressions, associated + types, semantic invariants, complexity guarantees, etc.) that a type must + fulfill to be correctly used as arguments in a call to a generic algorithm. + In C++, concepts are represented by formal template parameters to function + templates (generic algorithms). However, C++ has no explicit mechanism for + representing concepts—template parameters are merely placeholders. By + convention, these parameters are given names corresponding to the concept + that is required, but a C++ compiler does not enforce compliance to the + concept when the template parameter is bound to an actual type. + +

Naturally, if a generic algorithm is invoked with a type that does not + fulfill at least the syntactic requirements of the concept, a compile-time + error will occur. However, this error will not per se reflect the + fact that the type did not meet all of the requirements of the concept. + Rather, the error may occur deep inside the instantiation hierarchy at the + point where an expression is not valid for the type, or where a presumed + associated type is not available. The resulting error messages are largely + uninformative and basically impenetrable.

+ +

What is required is a mechanism for enforcing + “concept safety” at (or close to) the point + of instantiation. The Boost Concept Checking 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). We do not address + the semantic invariants or complexity guarantees, which are also part of + concept requirements..

+ +

Motivating + Example

+ +

We present a simple example to illustrate incorrect usage of a template + library and the resulting error messages. In the code below, the generic + std::stable_sort() algorithm from the Standard Template Library + (STL)[3, 4,5] is applied to a linked + list.

+
   bad_error_eg.cpp:
-   1  #include <list>
-   2  #include <algorithm>
-   3
-   4  int main(int, char*[]) {
-   5    std::list<int> v;
-   6    std::stable_sort(v.begin(), v.end());
-   7    return 0;
-   8  }
+1 #include <vector>
+2 #include <complex>
+3 #include <algorithm>
+4 
+5 int main()
+6 {
+7     std::vector<std::complex<float> > v;
+8     std::stable_sort(v.begin(), v.end());
+9 }
 
-Here, the -std::stable_sort() algorithm is prototyped as follows: -
+  

Here, the std::stable_sort() algorithm is prototyped as + follows:

+
   template <class RandomAccessIterator>
   void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
 
-Attempting to compile this code with Gnu C++ produces the following -compiler error. The output from other compilers is listed in the -Appendix. - -
-stl_algo.h: In function `void __merge_sort_loop<_List_iterator
-  <int,int &,int *>, int *, int>(_List_iterator<int,int &,int *>,
-  _List_iterator<int,int &,int *>, int *, int)':
-stl_algo.h:1448:   instantiated from `__merge_sort_with_buffer
-  <_List_iterator<int,int &,int *>, int *, int>(
-   _List_iterator<int,int &,int *>, _List_iterator<int,int &,int *>,
-   int *, int *)'
-stl_algo.h:1485:   instantiated from `__stable_sort_adaptive<
-  _List_iterator<int,int &,int *>, int *, int>(_List_iterator
-  <int,int &,int *>, _List_iterator<int,int &,int *>, int *, int)'
-stl_algo.h:1524:   instantiated from here
-stl_algo.h:1377: no match for `_List_iterator<int,int &,int *> & -
-  _List_iterator<int,int &,int *> &'
+  

Attempting to compile this code with Gnu C++ produces the following + compiler error:

+
+/usr/include/c++/4.1.2/bits/stl_algo.h: In function ‘void std::
+  __insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with 
+  _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
+  >*, std::vector<std::complex<float>, std::allocator<std::complex<
+  float> > > >]’:
+/usr/include/c++/4.1.2/bits/stl_algo.h:3066:   instantiated from ‘void 
+  std::__inplace_stable_sort(_RandomAccessIterator, 
+  _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::
+  __normal_iterator<std::complex<float>*, std::vector<std::complex<
+  float>, std::allocator<std::complex<float> > > >]’
+/usr/include/c++/4.1.2/bits/stl_algo.h:3776:   instantiated from ‘void 
+  std::stable_sort(_RandomAccessIterator, _RandomAccessIterator) [with 
+  _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
+  >*, std::vector<std::complex<float>, std::allocator<std::complex<
+  float> > > >]’
+bad_error_eg.cpp:8:   instantiated from here
+/usr/include/c++/4.1.2/bits/stl_algo.h:2277: error: no match for 
+  ‘operator<’ in ‘__val < __first. __gnu_cxx::__normal_iterator<
+  _Iterator, _Container>::operator* [with _Iterator = std::complex<float
+  >*, _Container = std::vector<std::complex<float>, std::allocator<
+  std::complex<float> > >]()’
 
-In this case, the fundamental error is that -std:list::iterator does not model the concept of -RandomAccessIterator. The list iterator is only bidirectional, not -fully random access (as would be a vector iterator). Unfortunately, -there is nothing in the error message to indicate this to the user. +

In this case, the fundamental error is + that std:complex<float> does not model the LessThanComparable + concept. Unfortunately, there is nothing in the error message to + indicate that to the user.

-

-To a C++ programmer having enough experience with template libraries -the error may be obvious. However, for the uninitiated, there are several -reasons why this message would be hard to understand. +

The error may be obvious to a C++ programmer having enough + experience with template libraries, but there are several reasons + why this message could be hard for the uninitiated to + understand:

-
    -
  1. The location of the error, line 6 of bad_error_eg.cpp - is not pointed to by the error message, despite the fact that Gnu C++ - prints up to 4 levels deep in the instantiation stack. -
  2. There is no textual correlation between the error message and the - documented requirements for std::stable_sort() and for - -RandomAccessIterator. -
  3. The error message is overly long, listing functions internal - to the STL that the user does not (and should not!) know or care - about. -
  4. With so many internal library functions listed in the error - message, the programmer could easily infer that the error is due - to the library, rather than to his or her own code. -
+
    +
  1. There is no textual correlation between the error message and the + documented requirements for std::stable_sort() and for LessThanComparable.
  2. -The following is an example of what we might expect from a more -informative message (and is in fact what the Boost Concept Checking -Library produces): +
  3. The error message is overly long, listing functions internal + to the STL (e.g. __insertion_sort) that the user + does not (and should not!) know or care about.
  4. -
    -boost/concept_check.hpp: In method `void LessThanComparableConcept
    -  <_List_iterator<int,int &,int *> >::constraints()':
    -boost/concept_check.hpp:334:   instantiated from `RandomAccessIteratorConcept
    -  <_List_iterator<int,int &,int *> >::constraints()'
    -bad_error_eg.cpp:6:   instantiated from `stable_sort<_List_iterator
    -  <int,int &,int *> >(_List_iterator<int,int &,int *>, 
    -  _List_iterator<int,int &,int *>)'
    -boost/concept_check.hpp:209: no match for `_List_iterator<int,int &,int *> &
    -  < _List_iterator<int,int &,int *> &'
    +    
  5. With so many internal library functions listed in the error message, + the programmer could easily infer that the problem is in the library, + rather than in his or her own code.
  6. +
+ +

The following is an example of what we might expect from a more + informative message (and is in fact what the Boost Concept Checking Library + produces):

+
+boost/concept_check.hpp: In destructor ‘boost::LessThanComparable<TT>::~
+  LessThanComparable() [with TT = std::complex<float>]’:
+boost/concept/detail/general.hpp:29:   instantiated from ‘static void boost::
+  concept::requirement<Model>::failed() [with Model = boost::
+  LessThanComparable<std::complex<float> >]’
+boost/concept/requires.hpp:30:   instantiated from ‘boost::_requires_<void
+  (*)(boost::LessThanComparable<std::complex<float> >)>’
+bad_error_eg.cpp:8:   instantiated from here
+boost/concept_check.hpp:236: error: no match for ‘operator<’ in ‘((boost::
+  LessThanComparable<std::complex<float> >*)this)->boost::
+  LessThanComparable<std::complex<float> >::a < ((boost::
+  LessThanComparable<std::complex<float> >*)this)->boost::
+  LessThanComparable<std::complex<float> >::b’
 
-This message rectifies several of the shortcomings of the standard -error messages. +

This message rectifies several of the shortcomings of the standard error + messages.

-
    -
  • The location of the error, bad_error_eg.cpp:6 is - specified in the error message. -
  • The message refers explicitly to concepts that the user can look - up in the STL documentation ( -RandomAccessIterator). -
  • The error message is now much shorter and does not reveal - internal STL functions. -
  • The presence of concept_check.hpp and - constraints() in the error message alerts the user to the - fact that the error lies in the user code and not in the library - implementation. -
+
    +
  • The message refers explicitly to concepts that the user can look up + in the STL documentation (LessThanComparable).
  • -

    History

    +
  • The error message is now much shorter and does not reveal + internal STL functions, nor indeed does it even point + to std::stable_sort.
  • -An earlier version of this concept checking system was developed by -the author while working at SGI in their C++ compiler and library -group. The earlier version is now part of the SGI STL distribution. The -boost concept checking library differs from the concept checking in -the SGI STL in that the definition of concept checking classes has -been greatly simplified, at the price of less helpful verbiage in the -error messages. +
  • The presence of concept_check.hpp in the error message + alerts the user to the fact that the error lies in the user code and not + in the library implementation.
  • +
-

Publications

+

History

- +

The first version of this concept checking system was developed + by Jeremy Siek while working at SGI in their C++ compiler and + library group. That version is now part of the SGI STL + distribution. The system originally introduced as the boost concept + checking library differs from concept checking in the SGI STL in + that the definition of concept checking classes was greatly + simplified, at the price of less helpful verbiage in the error + messages. In 2006 the system was rewritten (preserving backward + compatibility) by Dave Abrahams to be easier to use, more similar to + the proposed concept support the C++ core language, and to give + better error messages. +

-

Acknowledgements

+

Publications

-The idea to use function pointers to cause instantiation is due to -Alexander Stepanov. I am not sure of the origin of the idea to use -expressions to do up-front checking of templates, but it did appear in -D&E[ -2]. -Thanks to Matt Austern for his excellent documentation and -organization of the STL concepts, upon which these concept checks -are based. Thanks to Boost members for helpful comments and -reviews. + +

Acknowledgements

The idea to use function + pointers to cause instantiation is due to Alexander Stepanov. We are not sure + of the origin of the idea to use expressions to do up-front checking of + templates, but it did appear in D&E[ 2]. Thanks to Matt + Austern for his excellent documentation and organization of the STL + concepts, upon which these concept checks are based. Thanks to Boost + members for helpful comments and reviews. -

-Next: Using Concept Checks +

Next: Using Concept + Checks

+
-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+ + + - - + + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), + 2007 David Abrahams. +
+ + diff --git a/concept_check_fail_expected.cpp b/concept_check_fail_expected.cpp index 789bdf4..15bfe7a 100644 --- a/concept_check_fail_expected.cpp +++ b/concept_check_fail_expected.cpp @@ -1,4 +1,4 @@ -// (C) Copyright Jeremy Siek 2000. +// (C) Copyright Jeremy Siek, David Abrahams 2000-2006. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -11,8 +11,8 @@ /* - This file verifies that function_requires() of the Boost Concept - Checking Library catches errors when it is suppose to. + This file verifies that BOOST_CONCEPT_ASSERT catches errors in + function context. */ @@ -21,6 +21,6 @@ struct foo { }; int main() { - boost::function_requires< boost::EqualityComparableConcept >(); - return 0; + BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); + return 0; } diff --git a/concept_check_test.cpp b/concept_check_test.cpp index 070988b..f39ced7 100644 --- a/concept_check_test.cpp +++ b/concept_check_test.cpp @@ -25,76 +25,76 @@ main() // Basic Concepts { typedef default_constructible_archetype<> foo; - function_requires< DefaultConstructibleConcept >(); + function_requires< DefaultConstructible >(); } { typedef assignable_archetype<> foo; - function_requires< AssignableConcept >(); + function_requires< Assignable >(); } { typedef copy_constructible_archetype<> foo; - function_requires< CopyConstructibleConcept >(); + function_requires< CopyConstructible >(); } { typedef sgi_assignable_archetype<> foo; - function_requires< SGIAssignableConcept >(); + function_requires< SGIAssignable >(); } { typedef copy_constructible_archetype<> foo; typedef convertible_to_archetype convertible_to_foo; - function_requires< ConvertibleConcept >(); + function_requires< Convertible >(); } { - function_requires< ConvertibleConcept >(); + function_requires< Convertible >(); } { typedef equality_comparable_archetype<> foo; - function_requires< EqualityComparableConcept >(); + function_requires< EqualityComparable >(); } { typedef less_than_comparable_archetype<> foo; - function_requires< LessThanComparableConcept >(); + function_requires< LessThanComparable >(); } { typedef comparable_archetype<> foo; - function_requires< ComparableConcept >(); + function_requires< Comparable >(); } { typedef equal_op_first_archetype<> First; typedef equal_op_second_archetype<> Second; - function_requires< EqualOpConcept >(); + function_requires< EqualOp >(); } { typedef not_equal_op_first_archetype<> First; typedef not_equal_op_second_archetype<> Second; - function_requires< NotEqualOpConcept >(); + function_requires< NotEqualOp >(); } { typedef less_than_op_first_archetype<> First; typedef less_than_op_second_archetype<> Second; - function_requires< LessThanOpConcept >(); + function_requires< LessThanOp >(); } { typedef less_equal_op_first_archetype<> First; typedef less_equal_op_second_archetype<> Second; - function_requires< LessEqualOpConcept >(); + function_requires< LessEqualOp >(); } { typedef greater_than_op_first_archetype<> First; typedef greater_than_op_second_archetype<> Second; - function_requires< GreaterThanOpConcept >(); + function_requires< GreaterThanOp >(); } { typedef greater_equal_op_first_archetype<> First; typedef greater_equal_op_second_archetype<> Second; - function_requires< GreaterEqualOpConcept >(); + function_requires< GreaterEqualOp >(); } { typedef copy_constructible_archetype<> Return; typedef plus_op_first_archetype First; typedef plus_op_second_archetype Second; - function_requires< PlusOpConcept >(); + function_requires< PlusOp >(); } //=========================================================================== @@ -102,70 +102,70 @@ main() { typedef generator_archetype > foo; - function_requires< GeneratorConcept > >(); + function_requires< Generator > >(); } #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION { - function_requires< GeneratorConcept< void_generator_archetype, void > >(); + function_requires< Generator< void_generator_archetype, void > >(); } #endif { typedef unary_function_archetype F; - function_requires< UnaryFunctionConcept >(); + function_requires< UnaryFunction >(); } { typedef binary_function_archetype F; - function_requires< BinaryFunctionConcept >(); + function_requires< BinaryFunction >(); } { typedef unary_predicate_archetype F; - function_requires< UnaryPredicateConcept >(); + function_requires< UnaryPredicate >(); } { typedef binary_predicate_archetype F; - function_requires< BinaryPredicateConcept >(); + function_requires< BinaryPredicate >(); } //=========================================================================== // Iterator Concepts { typedef input_iterator_archetype > Iter; - function_requires< InputIteratorConcept >(); + function_requires< InputIterator >(); } { typedef output_iterator_archetype Iter; - function_requires< OutputIteratorConcept >(); + function_requires< OutputIterator >(); } { typedef input_output_iterator_archetype Iter; - function_requires< InputIteratorConcept >(); - function_requires< OutputIteratorConcept >(); + function_requires< InputIterator >(); + function_requires< OutputIterator >(); } { typedef forward_iterator_archetype > Iter; - function_requires< ForwardIteratorConcept >(); + function_requires< ForwardIterator >(); } { typedef mutable_forward_iterator_archetype > Iter; - function_requires< Mutable_ForwardIteratorConcept >(); + function_requires< Mutable_ForwardIterator >(); } { typedef bidirectional_iterator_archetype > Iter; - function_requires< BidirectionalIteratorConcept >(); + function_requires< BidirectionalIterator >(); } { typedef mutable_bidirectional_iterator_archetype > Iter; - function_requires< Mutable_BidirectionalIteratorConcept >(); + function_requires< Mutable_BidirectionalIterator >(); } { typedef random_access_iterator_archetype > Iter; - function_requires< RandomAccessIteratorConcept >(); + function_requires< RandomAccessIterator >(); } { typedef mutable_random_access_iterator_archetype > Iter; - function_requires< Mutable_RandomAccessIteratorConcept >(); + function_requires< Mutable_RandomAccessIterator >(); } //=========================================================================== diff --git a/concept_covering.htm b/concept_covering.htm index dfadd60..96c3208 100644 --- a/concept_covering.htm +++ b/concept_covering.htm @@ -1,126 +1,125 @@ - - - -Concept Covering and Archetypes - -C++ Boost + -
+ + + + + -

Concept Covering and Archetypes

+ + -We have discussed how it is important to select the minimal -requirements (concepts) for the inputs to a component, but it is -equally important to verify that the chosen concepts cover the -algorithm. That is, any possible user error should be caught by the -concept checks and not let slip through. Concept coverage can be -verified through the use of archetype classes. An archetype -class is an exact implementation of the interface associated with a -particular concept. The run-time behavior of the archetype class is -not important, the functions can be left empty. A simple test program -can then be compiled with the archetype classes as the inputs to the -component. If the program compiles then one can be sure that the -concepts cover the component. + Concept Covering and Archetypes + + + -The following code shows the archetype class for the Input -Iterator concept. Some care must be taken to ensure that the -archetype is an exact match to the concept. For example, the concept -states that the return type of operator*() must be -convertible to the value type. It does not state the more stringent -requirement that the return type be T& or const -T&. That means it would be a mistake to use T& -or const T& for the return type of the archetype -class. The correct approach is to create an artificial return type -that is convertible to T, as we have done here with -reference. The validity of the archetype class test is -completely dependent on it being an exact match with the concept, -which must be verified by careful (manual) inspection. + + C++ Boost
-
-  template <class T>
-  class input_iterator_archetype
-  {
-  private:
-    typedef input_iterator_archetype self;
-  public:
-    typedef std::input_iterator_tag iterator_category;
-    typedef T value_type;
-    struct reference {
-      operator const value_type&() const { return static_object<T>::get(); }
-    };
-    typedef const T* pointer;
-    typedef std::ptrdiff_t difference_type;
-    self& operator=(const self&) { return *this;  }
-    bool operator==(const self&) const { return true; }
-    bool operator!=(const self&) const { return true; }
-    reference operator*() const { return reference(); }
-    self& operator++() { return *this; }
-    self operator++(int) { return *this; }
+  

Concept Covering and + Archetypes

+ +

We have discussed how it is important to select the minimal requirements + (concepts) for the inputs to a component, but it is equally important to + verify that the chosen concepts cover the algorithm. That is, any + possible user error should be caught by the concept checks and not let slip + through. Concept coverage can be verified through the use of archetype + classes. An archetype class is an exact implementation of the interface + associated with a particular concept. The run-time behavior of the + archetype class is not important, the functions can be left empty. A simple + test program can then be compiled with the archetype classes as the inputs + to the component. If the program compiles then one can be sure that the + concepts cover the component. The following code shows the archetype class + for the Input + Iterator concept. Some care must be taken to ensure that the archetype + is an exact match to the concept. For example, the concept states that the + return type of operator*() must be convertible to the value type. + It does not state the more stringent requirement that the return type be + T& or const T&. That means it would be a mistake + to use T& or const T& for the return type of the + archetype class. The correct approach is to create an artificial return + type that is convertible to T, as we have done here with + reference. The validity of the archetype class test is completely + dependent on it being an exact match with the concept, which must be + verified by careful (manual) inspection.

+
+template <class T>
+class input_iterator_archetype
+{
+private:
+  typedef input_iterator_archetype self;
+public:
+  typedef std::input_iterator_tag iterator_category;
+  typedef T value_type;
+  struct reference {
+    operator const value_type&() const { return static_object<T>::get(); }
   };
+  typedef const T* pointer;
+  typedef std::ptrdiff_t difference_type;
+  self& operator=(const self&) { return *this;  }
+  bool operator==(const self&) const { return true; }
+  bool operator!=(const self&) const { return true; }
+  reference operator*() const { return reference(); }
+  self& operator++() { return *this; }
+  self operator++(int) { return *this; }
+};
 
-Generic algorithms are often tested by being instantiated with a -number of common input types. For example, one might apply -std::stable_sort() with basic pointer types as the iterators. -Though appropriate for testing the run-time behavior of the algorithm, -this is not helpful for ensuring concept coverage because C++ types -never match particular concepts, they often provide much more than the -minimal functionality required by any one concept. That is, even -though the function template compiles with a given type, the concept -requirements may still fall short of covering the functions actual -requirements. This is why it is important to compile with archetype -classes in addition to testing with common input types. +

Generic algorithms are often tested by being instantiated with a number + of common input types. For example, one might apply + std::stable_sort() with basic pointer types as the iterators. + Though appropriate for testing the run-time behavior of the algorithm, this + is not helpful for ensuring concept coverage because C++ types never match + particular concepts exactly. Instead, they often provide more than the + minimal functionality required by any one concept. Even though the function + template has concept checks, and compiles with a given type, the checks may + still fall short of covering all the functionality that is actually used. + This is why it is important to compile with archetype classes in addition + to testing with common input types.

-

-The following is an excerpt from stl_concept_covering.cpp -that shows how archetypes can be used to check the requirement -documentation for - -std::stable_sort(). In this case, it looks like the CopyConstructible and Assignable requirements were -forgotten in the SGI STL documentation (try removing those -archetypes). The Boost archetype classes have been designed so that -they can be layered. In this example the value type of the iterator -is composed out of three archetypes. In the archetype class reference -below, template parameters named Base indicate where the -layered archetype can be used. - -

-  {
-    typedef less_than_comparable_archetype< 
-        sgi_assignable_archetype<> > ValueType;
-    random_access_iterator_archetype<ValueType> ri;
-    std::stable_sort(ri, ri);
-  }
+  

The following is an excerpt from stl_concept_covering.cpp that + shows how archetypes can be used to check the requirement documentation for + std::stable_sort(). + In this case, it looks like the CopyConstructible and Assignable requirements were forgotten in + the SGI STL documentation (try removing those archetypes). The Boost + archetype classes have been designed so that they can be layered. In this + example the value type of the iterator is composed out of three archetypes. + In the archetype class + reference, template parameters named Base indicate where the + layered archetype paradigm can be used.

+
+{
+  typedef less_than_comparable_archetype< 
+      sgi_assignable_archetype<> > ValueType;
+  random_access_iterator_archetype<ValueType> ri;
+  std::stable_sort(ri, ri);
+}
 
-Next: Programming with Concepts
-Prev: Creating Concept Checking Classes +

Next: Programming with + Concepts
+ Prev: Creating Concept Checking + Classes
+


-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+ + + - - + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), + 2007 David Abrahams. +
+ + diff --git a/creating_concepts.htm b/creating_concepts.htm index d19ca01..f6cca8f 100644 --- a/creating_concepts.htm +++ b/creating_concepts.htm @@ -1,110 +1,157 @@ - - - -Creating Concept Checking Classes - -C++ Boost + -
+ + + + + + + + -

Creating Concept Checking Classes

+ Creating Concept Checking Classes + + -As an example of how to create a concept checking class, we look -at how to create the corresponding checks for the - -RandomAccessIterator concept. First, as a convention we name the -concept checking class after the concept, and add the suffix -``Concept''. Next we must define a member function named -constraints() in which we will exercise the valid expressions -of the concept. function_requires() expects this function's -signature to appear exactly as it is appears below: a void -non-const member function with no parameters. + + C++ Boost
-

-The first part of the constraints() function includes -the requirements that correspond to the refinement relationship -between -RandomAccessIterator and the concepts which it builds upon: - -BidirectionalIterator and - -LessThanComparable. We could have instead used -BOOST_CLASS_REQUIRE and placed these requirements in the class -body, however BOOST_CLASS_REQUIRE uses C++ language features that -are less portable. +

Creating + Concept Checking Classes

-

-Next we check that the iterator_category of the iterator is -either std::random_access_iterator_tag or a derived class. -After that we write out some code that corresponds to the valid -expressions of the -RandomAccessIterator concept. Typedefs can also be added to -enforce the associated types of the concept. +

As an example of how to create a concept checking class template, we + look at how to create the corresponding checks for the InputIterator concept. + The complete definition is here:

+
+template <class X>
+struct InputIterator
+  : Assignable<X>, EqualityComparable<X>
+{
+ private:
+    typedef std::iterator_traits<X> t;
+ public:
+    typedef typename t::value_type value_type;
+    typedef typename t::difference_type difference_type;
+    typedef typename t::reference reference;
+    typedef typename t::pointer pointer;
+    typedef typename t::iterator_category iterator_category;
 
-
-  template <class Iter>
-  struct RandomAccessIteratorConcept
-  {
-    void constraints() {
-      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;
-      i -= n;
-      i = i - n;
-      n = i - j;
-      i[n];
+    BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
+    BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
+        
+    BOOST_CONCEPT_USAGE(InputIterator)
+    {
+        X j(i);             // require copy construction
+        same_type(*i++,v);  // require postincrement-dereference returning value_type
+        X& x = ++j;         // require preincrement returning X&
     }
-    Iter i, j;
-    typename std::iterator_traits<Iter>::difference_type n;
-  };
+    
+ private:
+    X i;
+    value_type v;
+
+    // Type deduction will fail unless the arguments have the same type.
+    template <typename T>
+    void same_type(T const&, T const&);
+};
+
+ +

Walkthrough

+ +

First, as a convention we name the concept checking class after the + concept. Next, since InputIterator is a refinement of Assignable and + EqualityComparable, we derive its concept checking class from the checking + classes for those other concepts. The library will automatically check for + conformance to Assignable and EqualityComparable whenever it checks the + InputIterator concept.

+ +

Next, we declare the concept's associated types + as member typedefs. The associated difference type is required to be a + signed integer, and the iterator category has to be convertible to + std::input_iterator_tag, so we assert those relationships. The syntax for + accessing associated types through the concept-checking template mirrors + the proposed + syntax for associated type access in C++0x Finally, we use the + BOOST_CONCEPT_USAGE macro to declare the function that + exercises all the concept's valid expressions. Note that at this point you + may sometimes need to be a little creative: for example, to check that + *i++ returns the iterator's value type, we pass both values to + the same_type member function template, which requires both + arguments to have the same type, modulo references and cv-qualification. + It's an imperfect check, but it's better than nothing.

+ +

Values for Usage Patterns Should Be Data Members

+ +

You may be wondering why we declared i and v + as data members in the example above. Why didn't we simply write the + following?

+
+BOOST_CONCEPT_USAGE(InputIterator)
+{
+    X i;                // create the values we need
+    value_type v;
+
+    X j(i);             // require copy construction
+    same_type(*i++,v);  // require postincrement-dereference returning value_type
+    X& x = ++j;         // require preincrement returning X&
 }
 
-One potential pitfall in designing concept checking classes is using -more expressions in the constraint function than necessary. For -example, it is easy to accidentally use the default constructor to -create the objects that will be needed in the expressions (and not all -concepts require a default constructor). This is the reason we write -the constraint function as a member function of a class. The objects -involved in the expressions are declared as data members of the class. -Since objects of the constraints class template are never -instantiated, the default constructor for the concept checking class -is never instantiated. Hence the data member's default constructors -are never instantiated (C++ Standard Section 14.7.1 9). +

Unfortunately, that code wouldn't have worked out so well, because it + unintentionally imposes the requirement that X and its value + type are both default-constructible. On the other hand, since instances of + the InputIterator template will never be constructed, the + compiler never has to check how its data members will be constructed (C++ + Standard Section 14.7.1 9). For that reason you should always + declare values needed for usage patterns as data members.

-

-Next: Concept Covering and Archetypes
-Prev: Using Concept Checks +

These sorts of errors in concept definitions can be detected by the use + of Concept Archetypes, but it's always + better to avoid them pre-emptively.

+

Similarity to Proposed C++0x Language Support for Concepts

-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+

This library's syntaxes for concept refinement and for access of + associated types mirrors the corresponding proposed + syntaxes in C++0x. However, C++0x will use + “signatures” rather than usage patterns to + describe the valid operations on types participating in a concept, so when + converting your concept checking classes into language-supported concepts, + you'll need to translate your usage function into a series of + signatures.

- - +

Next: Concept Covering and + Archetypes
+ Prev: Using Concept + Checks

+
+ + + + + + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), + 2007 David Abrahams. +
+ + diff --git a/fake_sort.hpp b/fake_sort.hpp new file mode 100755 index 0000000..99c7546 --- /dev/null +++ b/fake_sort.hpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP +# define BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP + +# include +# include +# include + +namespace fake +{ + using namespace boost; + + template + BOOST_CONCEPT_REQUIRES( + ((Mutable_RandomAccessIterator)) + ((LessThanComparable::value_type>)) + + , (void)) + sort(RanIter,RanIter) + { + + } +} + +#endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP diff --git a/function_requires_fail.cpp b/function_requires_fail.cpp new file mode 100755 index 0000000..03beaec --- /dev/null +++ b/function_requires_fail.cpp @@ -0,0 +1,26 @@ +// (C) Copyright Jeremy Siek 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include + +/* + + This file verifies that function_requires() of the Boost Concept + Checking Library catches errors when it is suppose to. + +*/ + +struct foo { }; + +int +main() +{ + boost::function_requires< boost::EqualityComparable >(); + return 0; +} diff --git a/implementation.htm b/implementation.htm index b2c3db9..6df94ca 100644 --- a/implementation.htm +++ b/implementation.htm @@ -1,50 +1,59 @@ - - - -Concept Checking Implementation - -C++ Boost + -
+ + + + + + + + + -

Implementation

+ Concept Checking Implementation + -Ideally we would like to catch, and indicate, the concept violation at -the point of instantiation. As mentioned in D&E[2], the error -can be caught by exercising all of the requirements needed by the -function template. Exactly how the requirements (the valid -expressions in particular) are exercised is a tricky issue, since we -want the code to be compiled --- but not executed. Our -approach is to exercise the requirements in a separate function that -is assigned to a function pointer. In this case, the compiler will -instantiate the function but will not actually invoke it. In -addition, an optimizing compiler will remove the pointer assignment as -``dead code'' (though the run-time overhead added by the assignment -would be trivial in any case). It might be conceivable for a compiler -to skip the semantic analysis and compilation of the constraints -function in the first place, which would make our function pointer -technique ineffective. However, this is unlikely because removal of -unnecessary code and functions is typically done in later stages of a -compiler. We have successfully used the function pointer technique -with GNU C++, Microsoft Visual C++, and several EDG-based compilers -(KAI C++, SGI MIPSpro). The following code shows how this technique -can be applied to the std::stable_sort() function: + + C++ Boost
-
+  

Warning

+ +

This documentation is out-of-date; similar but + newer implementation techniques are now used. This documentation + also refers to components and protocols in the library's old + interace such as BOOST_CLASS_REQUIRES + and constraints() functions, which are still supported + but deprecated.

+ +

Implementation

+ +

Ideally we would like to catch, and indicate, the concept violation at + the point of instantiation. As mentioned in D&E[2], the error can be + caught by exercising all of the requirements needed by the function + template. Exactly how the requirements (the valid expressions in + particular) are exercised is a tricky issue, since we want the code to be + compiled—but not executed. Our approach is to exercise the + requirements in a separate function that is assigned to a function pointer. + In this case, the compiler will instantiate the function but will not + actually invoke it. In addition, an optimizing compiler will remove the + pointer assignment as ``dead code'' (though the run-time overhead added by + the assignment would be trivial in any case). It might be conceivable for a + compiler to skip the semantic analysis and compilation of the constraints + function in the first place, which would make our function pointer + technique ineffective. However, this is unlikely because removal of + unnecessary code and functions is typically done in later stages of a + compiler. We have successfully used the function pointer technique with GNU + C++, Microsoft Visual C++, and several EDG-based compilers (KAI C++, SGI + MIPSpro). The following code shows how this technique can be applied to the + std::stable_sort() function:

+
   template <class RandomAccessIterator>
   void stable_sort_constraints(RandomAccessIterator i)
   {
@@ -57,24 +66,23 @@ can be applied to the std::stable_sort() function:
   void stable_sort(RandomAccessIterator first, RandomAccessIterator last)
   {
     typedef void (*fptr_type)(RandomAccessIterator);
-    fptr_type x = &stable_sort_constraints;
+    fptr_type x = &stable_sort_constraints;
     ...
   }
 
-There is often a large set of requirements that need to be checked, -and it would be cumbersome for the library implementor to write -constraint functions like stable_sort_constraints() for every -public function. Instead, we group sets of valid expressions -together, according to the definitions of the corresponding concepts. -For each concept we define a concept checking class template where the -template parameter is for the type to be checked. The class contains -a contraints() member function which exercises all of the -valid expressions of the concept. The objects used in the constraints -function, such as n and i, are declared as data -members of the concept checking class. - -
+  

There is often a large set of requirements that need to be checked, and + it would be cumbersome for the library implementor to write constraint + functions like stable_sort_constraints() for every public + function. Instead, we group sets of valid expressions together, according + to the definitions of the corresponding concepts. For each concept we + define a concept checking class template where the template parameter is + for the type to be checked. The class contains a contraints() + member function which exercises all of the valid expressions of the + concept. The objects used in the constraints function, such as n + and i, are declared as data members of the concept checking + class.

+
   template <class Iter>
   struct RandomAccessIteratorConcept
   {
@@ -90,18 +98,14 @@ members of the concept checking class.
   };
 
-We can still use the function pointer mechanism to cause instantiation -of the constraints function, however now it will be a member function -pointer. To make it easy for the library implementor to invoke the -concept checks, we wrap the member function pointer mechanism in a -function named function_requires(). The following code -snippet shows how to use function_requires() to make sure -that the iterator is a - -RandomAccessIterator. - -
+  

We can still use the function pointer mechanism to cause instantiation + of the constraints function, however now it will be a member function + pointer. To make it easy for the library implementor to invoke the concept + checks, we wrap the member function pointer mechanism in a function named + function_requires(). The following code snippet shows how to use + function_requires() to make sure that the iterator is a RandomAccessIterator.

+
   template <class Iter>
   void stable_sort(Iter first, Iter last)
   {
@@ -110,16 +114,15 @@ RandomAccessIterator.
   }
 
-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. - -
+  

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.

+
   template <class Concept>
   void function_requires()
   {
@@ -128,17 +131,16 @@ everything in a do-while loop to prevent name collisions.
   }
 
-To check the type parameters of class templates, we provide the -BOOST_CLASS_REQUIRE macro which can be used inside the body of a -class definition (whereas function_requires() 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. - -
+  

To check the type parameters of class templates, we provide the + BOOST_CLASS_REQUIRE macro which can be used inside the body of a + class definition (whereas function_requires() 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.

+
 #define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
   typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
   template <func##type_var##concept _Tp1> \
@@ -148,14 +150,12 @@ typedef names to help prevent name collisions.
     concept_checking_typedef_##type_var##concept
 
-In addition, there are versions of BOOST_CLASS_REQUIRE that -take more arguments, to handle concepts that include interactions -between two or more types. BOOST_CLASS_REQUIRE was not used -in the implementation of the BCCL concept checks because some -compilers do not implement template parameters of function pointer -type. - - +-->

-

-Next: Reference
-Prev: Programming With Concepts +

Next: Reference
+ Prev: Programming With + Concepts

+
-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+ + + - - + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), + 2007 David Abrahams. +
+ + diff --git a/old_concept_class_fail.cpp b/old_concept_class_fail.cpp new file mode 100755 index 0000000..be41037 --- /dev/null +++ b/old_concept_class_fail.cpp @@ -0,0 +1,28 @@ +// (C) Copyright Jeremy Siek, David Abrahams 2000-2006. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Change Log: +// 20 Jan 2001 - Added warning suppression (David Abrahams) + +#include "old_concepts.hpp" + +// This file verifies that concepts written the old way still catch +// errors in class context. This is not expected to work on compilers +// without SFINAE support. + +struct foo { }; + +class class_requires_test +{ + BOOST_CLASS_REQUIRE(foo, old, EqualityComparableConcept); +}; + +int +main() +{ + class_requires_test x; + (void)x; // suppress unused variable warning + return 0; +} diff --git a/old_concept_function_fail.cpp b/old_concept_function_fail.cpp new file mode 100755 index 0000000..6b7bf30 --- /dev/null +++ b/old_concept_function_fail.cpp @@ -0,0 +1,23 @@ +// (C) Copyright Jeremy Siek 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include "old_concepts.hpp" + +// This file verifies that concepts written the old way still catch +// errors in function context. This is not expected to work on +// compilers without SFINAE support. + +struct foo { }; + +int +main() +{ + boost::function_requires< old::EqualityComparableConcept >(); + return 0; +} diff --git a/old_concept_pass.cpp b/old_concept_pass.cpp new file mode 100755 index 0000000..e9601fc --- /dev/null +++ b/old_concept_pass.cpp @@ -0,0 +1,34 @@ +// (C) Copyright Jeremy Siek, David Abrahams 2000-2006. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include "old_concepts.hpp" + +// This test verifies that use of the old-style concept checking +// classes still compiles (but not that it detects constraint +// violations). We check them with the old-style macros just for +// completeness, since those macros stranslate into +// BOOST_CONCEPT_ASSERTs. + +struct foo { bool operator()(int) { return true; } }; +struct bar { bool operator()(int, char) { return true; } }; + + +class class_requires_test +{ + BOOST_CLASS_REQUIRE(int, old, EqualityComparableConcept); + typedef int* int_ptr; typedef const int* const_int_ptr; + BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, old, EqualOpConcept); + BOOST_CLASS_REQUIRE3(foo, bool, int, old, UnaryFunctionConcept); + BOOST_CLASS_REQUIRE4(bar, bool, int, char, old, BinaryFunctionConcept); +}; + +int +main() +{ + class_requires_test x; + boost::ignore_unused_variable_warning(x); + return 0; +} diff --git a/old_concepts.hpp b/old_concepts.hpp new file mode 100755 index 0000000..76fad3c --- /dev/null +++ b/old_concepts.hpp @@ -0,0 +1,67 @@ +// Copyright Jeremy Siek, David Abrahams 2000-2006. Distributed under +// the Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP +# define BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP + +#include + +namespace old +{ + template + void require_boolean_expr(const TT& t) { + bool x = t; + boost::ignore_unused_variable_warning(x); + } + + template + struct EqualityComparableConcept + { + void constraints() { + boost::require_boolean_expr(a == b); + boost::require_boolean_expr(a != b); + } + TT a, b; + }; + + template + struct UnaryFunctionConcept + { + // required in case any of our template args are const-qualified: + UnaryFunctionConcept(); + + void constraints() { + r = f(arg); // require operator() + } + Func f; + Arg arg; + Return r; + }; + + template + struct BinaryFunctionConcept + { + void constraints() { + r = f(first, second); // require operator() + } + Func f; + First first; + Second second; + Return r; + }; + +#define DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ + template \ + struct NAME { \ + void constraints() { (void)constraints_(); } \ + bool constraints_() { \ + return a OP b; \ + } \ + First a; \ + Second b; \ + } + + DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept); +} + +#endif // BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP diff --git a/prog_with_concepts.htm b/prog_with_concepts.htm index dd58d15..2aa9e22 100644 --- a/prog_with_concepts.htm +++ b/prog_with_concepts.htm @@ -1,57 +1,55 @@ - - - -Programming With Concepts - -C++ Boost + -
+ + + + + -

Programming with Concepts

+ + -The process of deciding how to group requirements into concepts and -deciding which concepts to use in each algorithm is perhaps the most -difficult (yet most important) part of building a generic library. -A guiding principle to use during this process is one we -call the requirement minimization principle. + Programming With Concepts + + + -

-Requirement Minimization Principle: Minimize the requirements -on the input parameters of a component to increase its reusability. + + C++ Boost
-

-There is natural tension in this statement. By definition, the input -parameters must be used by the component in order for the component to -accomplish its task (by ``component'' we mean a function or class -template). The challenge then is to implement the component in such a -way that makes the fewest assumptions (the minimum requirements) about -the inputs while still accomplishing the task. +

Programming with Concepts

-

-The traditional notions of abstraction tie in directly to the -idea of minimal requirements. The more abstract the input, the fewer -the requirements. Thus, concepts are simply the embodiment of generic -abstract data types in C++ template programming. +

The process of deciding how to group requirements into concepts and + deciding which concepts to use in each algorithm is perhaps the most + difficult (yet most important) part of building a generic library. A + guiding principle to use during this process is one we call the + requirement minimization principle.

-

-When designing the concepts for some problem domain it is important to -keep in mind their purpose, namely to express the requirements for the -input to the components. With respect to the requirement minimization -principle, this means we want to minimize concepts. +

Requirement Minimization Principle: Minimize the requirements on + the input parameters of a component to increase its reusability.

- +-->

-

-Minimality in concepts is a property associated with the underlying -semantics of the problem domain being represented. In the problem -domain of basic containers, requiring traversal in a single direction -is a smaller requirement than requiring traversal in both directions -(hence the distinction between -ForwardIterator and - -BidirectionalIterator). The semantic difference can be easily seen -in the difference between the set of concrete data structures that -have forward iterators versus the set that has bidirectional -iterators. For example, singly-linked lists would fall in the set of -data structures having forward iterators, but not bidirectional -iterators. In addition, the set of algorithms that one can implement -using only forward iterators is quite different than the set that can -be implemented with bidirectional iterators. Because of this, it is -important to factor families of requirements into rather fine-grained -concepts. For example, the requirements for iterators are factored -into the six STL iterator concepts (trivial, output, input, forward, -bidirectional, and random access). +

Minimality in concepts is a property associated with the underlying + semantics of the problem domain being represented. In the problem domain of + basic containers, requiring traversal in a single direction is a smaller + requirement than requiring traversal in both directions (hence the + distinction between ForwardIterator and + BidirectionalIterator). + The semantic difference can be easily seen in the difference between the + set of concrete data structures that have forward iterators versus the set + that has bidirectional iterators. For example, singly-linked lists would + fall in the set of data structures having forward iterators, but not + bidirectional iterators. In addition, the set of algorithms that one can + implement using only forward iterators is quite different than the set that + can be implemented with bidirectional iterators. Because of this, it is + important to factor families of requirements into rather fine-grained + concepts. For example, the requirements for iterators are factored into the + six STL iterator concepts (trivial, output, input, forward, bidirectional, + and random access).

-

-Next: Implementation
-Prev: Concept Covering and Archetypes +

Next: Implementation
+ Prev: Concept Covering and + Archetypes

+
-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+ + + - - + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), + 2007 David Abrahams. +
+ + diff --git a/reference.htm b/reference.htm index d99909f..0e1797b 100644 --- a/reference.htm +++ b/reference.htm @@ -1,308 +1,408 @@ - - - -Boost Concept Checking Reference - - -C++ Boost + -
+ + + + + -

Reference

+ + + + -
    -
  1. Functions
  2. -
  3. Macros
  4. -
  5. Basic Concept Checking Classes
  6. -
  7. Iterator Concept Checking Classes
  8. -
  9. Function Object Concept Checking Classes
  10. -
  11. Container Concept Checking Classes
  12. -
  13. Basic Archetype Classes
  14. -
  15. Iterator Archetype Classes
  16. -
  17. Function Object Archetype Classes
  18. -
  19. Container Archetype Classes
  20. -
+ Boost Concept Checking Reference + -

Functions

+ + C++ Boost
-
-  template <class Concept>
-  void function_requires();
+  

Reference

+ +
    +
  1. Macros
  2. + +
  3. Basic Concept Checking Classes
  4. + +
  5. Iterator Concept Checking + Classes
  6. + +
  7. Function Object Concept Checking + Classes
  8. + +
  9. Container Concept Checking + Classes
  10. + +
  11. Basic Archetype Classes
  12. + +
  13. Iterator Archetype Classes
  14. + +
  15. Function Object Archetype + Classes
  16. + +
  17. Container Archetype Classes
  18. + +
  19. Deprecated Functions
  20. + +
  21. Deprecated Macros
  22. + +
  23. Deprecated Concept + Checking Classes
  24. +
+ +

Macros

+
+#include "boost/concept/assert.hpp"
+
+BOOST_CONCEPT_ASSERT((concept checking class template specialization));
 
-

Macros

+

Effects: causes a compilation failure if the concept is + not satisfied.
+ Note: this macro can be used at global, class, or function + scope.

-
-  // Apply concept checks in class definitions.
-  BOOST_CLASS_REQUIRE(type, namespace-of-concept, concept);
-  BOOST_CLASS_REQUIRE2(type1, type2, namespace-of-concept, concept);
-  BOOST_CLASS_REQUIRE3(type1, type2, type3, namespace-of-concept, concept);
-  BOOST_CLASS_REQUIRE4(type1, type2, type3, type4, namespace-of-concept, concept);
+  
+#include "boost/concept/requires.hpp"
+
+template <…template parameters…>
+BOOST_CONCEPT_REQUIRES(
+  ((concept checking class template specialization1)) 
+  ((concept checking class template specialization2))… 
+  ((concept checking class template specializationn)),
+  (function return type)
+) function_template_name(…function parameters…)
 
-Deprecated macros: +

Effects: causes a compilation failure if the + given concepts are not satisfied.
+ Note: this macro is intended to be used in place of + a function template's return type.

-
-  // Apply concept checks in class definitions.
-  BOOST_CLASS_REQUIRES(type, concept);
-  BOOST_CLASS_REQUIRES2(type1, type2, concept);
-  BOOST_CLASS_REQUIRES3(type1, type2, type3, concept);
-  BOOST_CLASS_REQUIRES4(type1, type2, type3, type4, concept);
+  

Basic Concept Checking + Classes

+
+#include "boost/concept_check.hpp"
+
+template <class T>
+struct Integer; // Is T a built-in integer type?
+
+template <class T>
+struct SignedInteger; // Is T a built-in signed integer type?
+
+template <class T>
+struct UnsignedInteger; // Is T a built-in unsigned integer type?
+
+template <class X, class Y>
+struct Convertible; // Is X convertible to Y?
+
+template <class T>
+struct Assignable; // Standard ref 23.1
+
+template <class T>
+struct SGIAssignable;
+
+template <class T>
+struct DefaultConstructible;
+
+template <class T> 
+struct CopyConstructible; // Standard ref 20.1.3
+
+template <class T> 
+struct EqualityComparable; // Standard ref 20.1.1
+
+template <class T>
+struct LessThanComparable; // Standard ref 20.1.2
+
+template <class T>
+struct Comparable; // The SGI STL LessThanComparable concept
 
-

Basic Concept Checking Classes

+

Iterator Concept + Checking Classes

+
+template <class Iter>
+struct InputIterator; // Standard ref 24.1.1 Table 72
 
-
-  template <class T>
-  struct IntegerConcept; // Is T a built-in integer type?
+template <class Iter, class T> 
+struct OutputIterator; // Standard ref 24.1.2 Table 73
 
-  template <class T>
-  struct SignedIntegerConcept; // Is T a built-in signed integer type?
+template <class Iter> 
+struct ForwardIterator; // Standard ref 24.1.3 Table 74
 
-  template <class T>
-  struct UnsignedIntegerConcept; // Is T a built-in unsigned integer type?
+template <class Iter> 
+struct Mutable_ForwardIterator;
 
-  template <class X, class Y>
-  struct ConvertibleConcept; // Is X convertible to Y?
+template <class Iter> 
+struct BidirectionalIterator; // Standard ref 24.1.4 Table 75
 
-  template <class T>
-  struct AssignableConcept; // Standard ref 23.1
+template <class Iter> 
+struct Mutable_BidirectionalIterator;
 
-  template <class T>
-  struct SGIAssignableConcept;
+template <class Iter> 
+struct RandomAccessIterator; // Standard ref 24.1.5 Table 76
 
-  template <class T>
-  struct DefaultConstructibleConcept;
-
-  template <class T> 
-  struct CopyConstructibleConcept; // Standard ref 20.1.3
-
-  template <class T> 
-  struct EqualityComparableConcept; // Standard ref 20.1.1
-
-  template <class T>
-  struct LessThanComparableConcept; // Standard ref 20.1.2
-
-  template <class T>
-  struct ComparableConcept; // The SGI STL LessThanComparable concept
+template <class Iter> 
+struct Mutable_RandomAccessIterator;
 
-

Iterator Concept Checking Classes

+

Function Object Concept Checking + Classes

+
+#include "boost/concept_check.hpp"
 
-
-  template <class Iter>
-  struct InputIteratorConcept; // Standard ref 24.1.1 Table 72
+template <class Func, class Return>
+struct Generator;
 
-  template <class Iter, class T> 
-  struct OutputIteratorConcept; // Standard ref 24.1.2 Table 73
+template <class Func, class Return, class Arg>
+struct UnaryFunction;
 
-  template <class Iter> 
-  struct ForwardIteratorConcept; // Standard ref 24.1.3 Table 74
+template <class Func, class Return, class First, class Second>
+struct BinaryFunction;
 
-  template <class Iter> 
-  struct Mutable_ForwardIteratorConcept;
+template <class Func, class Arg>
+struct UnaryPredicate;
 
-  template <class Iter> 
-  struct BidirectionalIteratorConcept; // Standard ref 24.1.4 Table 75
+template <class Func, class First, class Second>
+struct BinaryPredicate;
 
-  template <class Iter> 
-  struct Mutable_BidirectionalIteratorConcept;
+template <class Func, class First, class Second>
+struct Const_BinaryPredicate;
 
-  template <class Iter> 
-  struct RandomAccessIteratorConcept; // Standard ref 24.1.5 Table 76
+template <class Func, class Return>
+struct AdaptableGenerator;
 
-  template <class Iter> 
-  struct Mutable_RandomAccessIteratorConcept;
+template <class Func, class Return, class Arg>
+struct AdaptableUnaryFunction;
+
+template <class Func, class First, class Second>
+struct AdaptableBinaryFunction;
+
+template <class Func, class Arg>
+struct AdaptablePredicate;
+
+template <class Func, class First, class Second>
+struct AdaptableBinaryPredicate;
 
-

Function Object Concept Checking Classes

+

Container Concept + Checking Classes

+
+#include "boost/concept_check.hpp"
 
-
-  template <class Func, class Return>
-  struct GeneratorConcept;
+template <class C>
+struct Container; // Standard ref 23.1 Table 65
 
-  template <class Func, class Return, class Arg>
-  struct UnaryFunctionConcept;
+template <class C>
+struct Mutable_Container;
 
-  template <class Func, class Return, class First, class Second>
-  struct BinaryFunctionConcept;
+template <class C>
+struct ForwardContainer;
 
-  template <class Func, class Arg>
-  struct UnaryPredicateConcept;
+template <class C>
+struct Mutable_ForwardContainer;
 
-  template <class Func, class First, class Second>
-  struct BinaryPredicateConcept;
+template <class C>
+struct ReversibleContainer; // Standard ref 23.1 Table 66
 
-  template <class Func, class First, class Second>
-  struct Const_BinaryPredicateConcept;
+template <class C>
+struct Mutable_ReversibleContainer;
 
-  template <class Func, class Return>
-  struct AdaptableGeneratorConcept;
+template <class C>
+struct RandomAccessContainer;
 
-  template <class Func, class Return, class Arg>
-  struct AdaptableUnaryFunctionConcept;
+template <class C>
+struct Mutable_RandomAccessContainer;
 
-  template <class Func, class First, class Second>
-  struct AdaptableBinaryFunctionConcept;
+template <class C>
+struct Sequence; // Standard ref 23.1.1
 
-  template <class Func, class Arg>
-  struct AdaptablePredicateConcept;
+template <class C>
+struct FrontInsertionSequence;
 
-  template <class Func, class First, class Second>
-  struct AdaptableBinaryPredicateConcept;
-  
+template <class C>
+struct BackInsertionSequence;
+
+template <class C>
+struct AssociativeContainer; // Standard ref 23.1.2 Table 69
+
+template <class C>
+struct UniqueAssociativeContainer;
+
+template <class C>
+struct MultipleAssociativeContainer;
+
+template <class C>
+struct SimpleAssociativeContainer;
+
+template <class C>
+struct PairAssociativeContainer;
+
+template <class C>
+struct SortedAssociativeContainer;
 
-

Container Concept Checking Classes

+

Basic Archetype + Classes

+
+#include "boost/concept_archetype.hpp"
 
-
-  template <class C>
-  struct ContainerConcept; // Standard ref 23.1 Table 65
+template <class T = int>
+class null_archetype; // A type that models no concepts.
 
-  template <class C>
-  struct Mutable_ContainerConcept;
+template <class Base = null_archetype>
+class default_constructible_archetype;
 
-  template <class C>
-  struct ForwardContainerConcept;
+template <class Base = null_archetype>
+class assignable_archetype;
 
-  template <class C>
-  struct Mutable_ForwardContainerConcept;
+template <class Base = null_archetype>
+class copy_constructible_archetype;
 
-  template <class C>
-  struct ReversibleContainerConcept; // Standard ref 23.1 Table 66
+template <class Base = null_archetype>
+class equality_comparable_archetype;
 
-  template <class C>
-  struct Mutable_ReversibleContainerConcept;
-
-  template <class C>
-  struct RandomAccessContainerConcept;
-
-  template <class C>
-  struct Mutable_RandomAccessContainerConcept;
-
-  template <class C>
-  struct SequenceConcept; // Standard ref 23.1.1
-
-  template <class C>
-  struct FrontInsertionSequenceConcept;
-
-  template <class C>
-  struct BackInsertionSequenceConcept;
-
-  template <class C>
-  struct AssociativeContainerConcept; // Standard ref 23.1.2 Table 69
-
-  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;
+template <class T, class Base = null_archetype>
+class convertible_to_archetype;
 
+

Iterator Archetype + Classes

+
+#include "boost/concept_archetype.hpp"
 
-

Basic Archetype Classes

+template <class ValueType> +class trivial_iterator_archetype; -
-  template <class T = int>
-  class null_archetype; // A type that models no concepts.
+template <class ValueType>
+class mutable_trivial_iterator_archetype;
 
-  template <class Base = null_archetype>
-  class default_constructible_archetype;
+template <class ValueType>
+class input_iterator_archetype;
 
-  template <class Base = null_archetype>
-  class assignable_archetype;
+template <class ValueType>
+class forward_iterator_archetype;
 
-  template <class Base = null_archetype>
-  class copy_constructible_archetype;
+template <class ValueType>
+class bidirectional_iterator_archetype;
 
-  template <class Base = null_archetype>
-  class equality_comparable_archetype;
-
-  template <class T, class Base = null_archetype>
-  class convertible_to_archetype;
+template <class ValueType>
+class random_access_iterator_archetype;
 
-

Iterator Archetype Classes

+

Function Object Archetype Classes

+
+#include "boost/concept_archetype.hpp"
 
-
-  template <class ValueType>
-  class trivial_iterator_archetype;
+template <class Arg, class Return>
+class unary_function_archetype;
 
-  template <class ValueType>
-  class mutable_trivial_iterator_archetype;
+template <class Arg1, class Arg2, class Return>
+class binary_function_archetype;
 
-  template <class ValueType>
-  class input_iterator_archetype;
-
-  template <class ValueType>
-  class forward_iterator_archetype;
-
-  template <class ValueType>
-  class bidirectional_iterator_archetype;
-
-  template <class ValueType>
-  class random_access_iterator_archetype;
+template <class Arg>
+class predicate_archetype;
 
+template <class Arg1, class Arg2>
+class binary_predicate_archetype;
 
-

Function Object Archetype Classes

- -
-  template <class Arg, class Return>
-  class unary_function_archetype;
-
-  template <class Arg1, class Arg2, class Return>
-  class binary_function_archetype;
-
-  template <class Arg>
-  class predicate_archetype;
-
-  template <class Arg1, class Arg2>
-  class binary_predicate_archetype;
-
- -

Container Archetype Classes

- -
+  

Container + Archetype Classes

+
 UNDER CONSTRUCTION
 
-

-Back to Introduction -
-Prev: Implementation +

Deprecated + Functions

+
+#include "boost/concept_check.hpp"
 
-
-
- - -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
+template <class Concept> +void function_requires(); +
- - +

Deprecated + Macros

+
+#include "boost/concept_check.hpp"
+
+// Apply concept checks in class definitions.
+BOOST_CLASS_REQUIRE(type, namespace-of-concept, concept);
+BOOST_CLASS_REQUIRE2(type1, type2, namespace-of-concept, concept);
+BOOST_CLASS_REQUIRE3(type1, type2, type3, namespace-of-concept, concept);
+BOOST_CLASS_REQUIRE4(type1, type2, type3, type4, namespace-of-concept, concept);
+
+// Apply concept checks in class definitions.
+BOOST_CLASS_REQUIRES(type, concept);
+BOOST_CLASS_REQUIRES2(type1, type2, concept);
+BOOST_CLASS_REQUIRES3(type1, type2, type3, concept);
+BOOST_CLASS_REQUIRES4(type1, type2, type3, type4, concept);
+
+ +

Deprecated Concept Checking + Classes

+ +

For each of the concepts documented here, the library includes an + identical concept checking class whose name ends in + “Concept” For example, in + addition to RandomAccessIterator, the library defines a + RandomAccessIteratorConcept class template.

+ +

Back to Introduction
+ Prev: Implementation

+
+ + + + + + + +
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), 2007 + David Abrahams.
+ + diff --git a/stl_concept_check.cpp b/stl_concept_check.cpp index f84e220..8ec6f96 100644 --- a/stl_concept_check.cpp +++ b/stl_concept_check.cpp @@ -20,7 +20,7 @@ #include #include #include -#ifndef BOOST_NO_SLIST +#if 0 #include #endif @@ -43,27 +43,27 @@ main() typedef std::list List; // VC++ missing pointer and const_pointer typedefs - function_requires< Mutable_RandomAccessContainerConcept >(); - function_requires< BackInsertionSequenceConcept >(); + function_requires< Mutable_RandomAccessContainer >(); + function_requires< BackInsertionSequence >(); #if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS)) #if !(defined(__sgi) && defined(BOOST_HIDE_EXPECTED_ERRORS)) // old deque iterator missing n + iter operation - function_requires< Mutable_RandomAccessContainerConcept >(); + function_requires< Mutable_RandomAccessContainer >(); #endif // warnings about signed and unsigned in old deque version - function_requires< FrontInsertionSequenceConcept >(); - function_requires< BackInsertionSequenceConcept >(); + function_requires< FrontInsertionSequence >(); + function_requires< BackInsertionSequence >(); #endif // VC++ missing pointer and const_pointer typedefs - function_requires< Mutable_ReversibleContainerConcept >(); - function_requires< FrontInsertionSequenceConcept >(); - function_requires< BackInsertionSequenceConcept >(); + function_requires< Mutable_ReversibleContainer >(); + function_requires< FrontInsertionSequence >(); + function_requires< BackInsertionSequence >(); -#ifndef BOOST_NO_SLIST +#if 0 typedef BOOST_STD_EXTENSION_NAMESPACE::slist SList; - function_requires< FrontInsertionSequenceConcept >(); + function_requires< FrontInsertionSequence >(); #endif typedef std::set Set; @@ -71,21 +71,21 @@ main() typedef std::map Map; typedef std::multimap MultiMap; - function_requires< SortedAssociativeContainerConcept >(); - function_requires< SimpleAssociativeContainerConcept >(); - function_requires< UniqueAssociativeContainerConcept >(); + function_requires< SortedAssociativeContainer >(); + function_requires< SimpleAssociativeContainer >(); + function_requires< UniqueAssociativeContainer >(); - function_requires< SortedAssociativeContainerConcept >(); - function_requires< SimpleAssociativeContainerConcept >(); - function_requires< MultipleAssociativeContainerConcept >(); + function_requires< SortedAssociativeContainer >(); + function_requires< SimpleAssociativeContainer >(); + function_requires< MultipleAssociativeContainer >(); - function_requires< SortedAssociativeContainerConcept >(); - function_requires< UniqueAssociativeContainerConcept >(); - function_requires< PairAssociativeContainerConcept >(); + function_requires< SortedAssociativeContainer >(); + function_requires< UniqueAssociativeContainer >(); + function_requires< PairAssociativeContainer >(); - function_requires< SortedAssociativeContainerConcept >(); - function_requires< MultipleAssociativeContainerConcept >(); - function_requires< PairAssociativeContainerConcept >(); + function_requires< SortedAssociativeContainer >(); + function_requires< MultipleAssociativeContainer >(); + function_requires< PairAssociativeContainer >(); #endif return 0; diff --git a/stl_concept_covering.cpp b/stl_concept_covering.cpp index 3d60a80..338d23f 100644 --- a/stl_concept_covering.cpp +++ b/stl_concept_covering.cpp @@ -177,7 +177,7 @@ main() typedef equal_op_first_archetype<> Left; typedef input_iterator_archetype InIter; InIter in; - function_requires< InputIteratorConcept >(); + function_requires< InputIterator >(); equal_op_second_archetype<> value(dummy_cons); std::iterator_traits::difference_type n = std::count(in, in, value); @@ -591,7 +591,7 @@ main() std::nth_element(ri, ri, ri, comp); } { -#if defined(__GNUC__) || defined(__IBMCPP__) +#if defined(__GNUC__) typedef less_than_op_first_archetype<> FT; typedef less_than_op_second_archetype<> T; #elif defined(__KCC) @@ -615,7 +615,7 @@ main() fi = std::lower_bound(fi, fi, value, comp); } { -#if defined(__GNUC__) || defined(__IBMCPP__) +#if defined(__GNUC__) // Note, order of T,FT is flipped from lower_bound typedef less_than_op_second_archetype<> FT; typedef less_than_op_first_archetype<> T; @@ -639,7 +639,7 @@ main() fi = std::upper_bound(fi, fi, value, comp); } { -#if defined(__GNUC__) || defined(__IBMCPP__) +#if defined(__GNUC__) typedef less_than_op_first_archetype< less_than_op_second_archetype< null_archetype<>, optag2>, optag1> FT; typedef less_than_op_second_archetype< @@ -669,7 +669,7 @@ main() ignore_unused_variable_warning(p); } { -#if defined(__GNUC__) || defined(__IBMCPP__) +#if defined(__GNUC__) typedef less_than_op_first_archetype< less_than_op_second_archetype, optag2>, optag1> FT; typedef less_than_op_second_archetype< @@ -686,7 +686,7 @@ main() { typedef null_archetype Arg1; typedef null_archetype Arg2; -#if defined(__GNUC__) || defined(__KCC) || defined(__IBMCPP__) +#if defined(__GNUC__) || defined(__KCC) typedef convertible_to_archetype > FT; typedef convertible_to_archetype Tout; -#if defined(__GNUC__) || defined(__KCC) || defined(__IBMCPP__) +#if defined(__GNUC__) || defined(__KCC) typedef less_than_op_first_archetype< less_than_op_second_archetype< convertible_to_archetype, optag2>, optag1 > Tin1; diff --git a/usage_fail.cpp b/usage_fail.cpp new file mode 100755 index 0000000..29796b9 --- /dev/null +++ b/usage_fail.cpp @@ -0,0 +1,22 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +template +struct StringInitializable +{ + typedef int associated; + BOOST_CONCEPT_USAGE(StringInitializable) + { + T x = "foo"; + } +}; + +// Test that accessing an associated type will actually exercise usage +// requirements +typedef StringInitializable::associated tee; + + + diff --git a/using_concept_check.htm b/using_concept_check.htm index ff120f8..3dc311d 100644 --- a/using_concept_check.htm +++ b/using_concept_check.htm @@ -1,227 +1,186 @@ - - - -Using Concept Checks - -C++ Boost + -
+ + + + + + + + -

Using Concept Checks

+ Using Concept Checks + + -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 (BCCL) includes concept checking classes -for all of the concepts used in the C++ standard library and a few -more. The Reference section lists these -concept checking classes. In addition, other boost libraries come with -concept checking classes for the concepts that are particular to those -libraries. For example, there are graph concepts and property map concepts. -Also, whenever anyone writing a class of function template -needs to express requirements that are not yet stated by an existing -concept, a new concept checking class should be created. How -to do this is explained in Creating -Concept Checking Classes. + + C++ Boost
-

-An example of a concept checking class from the BCCL is the -EqualityComparableConcept class. The class corresponds to the -EqualityComparable requirements described in 20.1.1 of the C++ -Standard, and to the EqualityComparable -concept documented in the SGI STL. +

Using Concept + Checks

-
-  template <class T>
-  struct EqualityComparableConcept;
+  

For each concept there is a concept checking class template that can be + used to make sure that a given type (or set of types) models the concept. + The Boost Concept Checking Library (BCCL) includes concept checking class + templates for all of the concepts used in the C++ standard library and a + few more. See the Reference section for a + complete list. In addition, other boost libraries come with concept + checking classes for the concepts that are particular to those libraries. + For example, there are graph + concepts and property map + concepts. Also, whenever anyone writing function templates needs + to express requirements that are not yet stated by an existing concept, a + new concept checking class should be created. How to do this is explained + in Creating Concept Checking + Classes.

+ +

An example of a concept checking class from the BCCL is the + EqualityComparableConcept class. The class corresponds to the + EqualityComparable requirements described in 20.1.1 of the C++ Standard, + and to the EqualityComparable + concept documented in the SGI STL.

+
+template <class T>
+struct EqualityComparable;
 
-The template argument T will the type to be checked. That is, -the purpose of EqualityComparableConcept is to make sure that -the template argument given for T models the -EqualityComparable concept. +

The template argument is the type to be checked. That is, the purpose of + EqualityComparable<X> is to make sure that + X models the EqualityComparable concept.

-

-Each concept checking class has a member function named -constraints() which contains the valid expressions for the -concept. To check whether some type is EqualityComparable we need to -instantiate the concept checking class with the type and then find a -way to get the compiler to compile the constraints() function -without actually executing the function. The Boost Concept Checking -Library defines two utilities that make this easy: -function_requires() and BOOST_CLASS_REQUIRE. +

BOOST_CONCEPT_ASSERT()

-

function_requires()

+

The most versatile way of checking concept requirements is to use the + BOOST_CONCEPT_ASSERT() macro. You can use this macro at any + scope, by passing a concept checking template specialization enclosed in + parentheses. Note: that means invocations of + BOOST_CONCEPT_ASSERT will appear to use double + parentheses.

+
+// In my library:
+template <class T>
+void generic_library_function(T x)
+{
+  BOOST_CONCEPT_ASSERT((EqualityComparable<T>));
+  // ...
+};
 
-The function_requires() function can be used in function bodies
-and the BOOST_CLASS_REQUIRE macro 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.
+template <class It>
+class generic_library_class
+{
+  BOOST_CONCEPT_ASSERT((RandomAccessIterator<It>));
+  // ...
+};
 
-
-  // In my library:
-  template <class T>
-  void generic_library_function(T x)
-  {
-    function_requires< EqualityComparableConcept<T> >();
-    // ...
-  };
+// In the user's code:  
+class foo {
+  //... 
+};
 
-  // In the user's code:  
-  class foo {
-    //... 
-  };
-
-  int main() {
-    foo f;
-    generic_library_function(f);
-    return 0;
-  }
+int main() {
+  foo x;
+  generic_library_function(x);
+  generic_library_class<std::vector<char>::iterator> y;
+  //... 
+}
 
+

BOOST_CONCEPT_REQUIRES

-

BOOST_CLASS_REQUIRE

+

One of the nice things about the proposed C++0x syntax + for declaring concept constrained function templates is the way that + constraints are part of the function declaration, so clients will + see them. BOOST_CONCEPT_ASSERT can only express constraints + within the function template definition, which hides the constraint in the + function body. Aside from the loss of a self-documenting interface, + asserting conformance only in the function body can undesirably delay + checking if the function is explicitly instantiated in a different + translation unit from the one in which it is called, or if the compiler + does link-time instantiation.

-The BOOST_CLASS_REQUIRE macro can be used inside a class -definition to check whether some type models a concept. Make sure -that the arguments to this macro are simply identifiers. You may need -to use typedef to get your types into this form. - -
-  // In my library:
-  template <class T>
-  struct generic_library_class
-  {
-    BOOST_CLASS_REQUIRE(T, boost, EqualityComparableConcept);
-    // ...
-  };
-
-  // In the user's code:  
-  class foo {
-    //... 
-  };
-
-  int main() {
-    generic_library_class<foo> glc;
-    // ...
-    return 0;
-  }
+  

The BOOST_CONCEPT_REQUIRES macro can be used in a function + template declaration to check whether some type models a concept. It + accepts two arguments, a list of constraints, and the + function template's return type. The list of constraints takes the form of + a sequence of adjacent concept checking template specializations, + in double parentheses, and the function's return type must + also be parenthesized. For example, the standard stable_sort + algorithm might be declared as follows: class

+
+template<typename RanIter>
+BOOST_CONCEPT_REQUIRES(
+    ((Mutable_RandomAccessIterator<RanIter>))
+    ((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)),
+    (void)) // return type
+    stable_sort(RanIter,RanIter);
 
+

Note that the algorithm requires that the value type of the iterator be + LessThanComparable, and it accesses that value type through the + Mutable_RandomAccessIterator concept checking template. In + general, the Boost concept checking classes expose associated types as + nested member typedefs so that you can use this syntax, which mimics the + approach used in the concept support proposed for the next version of + C++.

-

Example

+

Multi-Type Concepts

-

-Getting back to the earlier motivating example, -one good application of concept checks would be to 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 function_requires() to -check this. - -

-  template <class RandomAccessIter>
-  void stable_sort(RandomAccessIter first, RandomAccessIter last)
-  {
-    function_requires< RandomAccessIteratorConcept<RandomAccessIter> >();
-    typedef typename std::iterator_traits<RandomAccessIter>::value_type value_type;
-    function_requires< LessThanComparableConcept<value_type> >();
-    ...
-  }
+  

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 BOOST_CONCEPT_REQUIRES + is used with the ReadWritePropertyMap + concept, which takes two type parameters: a property map and the key type + for the map.

+
+template <class G, class Buffer, class BFSVisitor, 
+          class ColorMap>
+BOOST_CONCEPT_REQUIRES(
+  ((ReadWritePropertyMap<ColorMap, typename IncidenceGraph<G>::vertex_descriptor>)),
+  (void)) // return type
+breadth_first_search(G& g, 
+  typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
+  Buffer& Q, BFSVisitor vis, ColorMap color)
+{
+  typedef typename IncidenceGraph<G>::vertex_descriptor Vertex;
+  ...
+}
 
- - - - -

-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 -function_requires() is used with the ReadWritePropertyMap -concept which takes two type parameters: a property map and the key -type for the map. - -

-  template <class IncidenceGraph, class Buffer, class BFSVisitor, 
-            class ColorMap>
-  void breadth_first_search(IncidenceGraph& g, 
-    typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
-    Buffer& Q, BFSVisitor vis, ColorMap color)
-  {
-    typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
-    function_requires< ReadWritePropertyMap<ColorMap, Vertex> >();
-    ...
-  }
+  

Although 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. The syntactic + requirements, at least, can easily be checked by creating a small program + and using BOOST_CONCEPT_ASSERT with the type and concept in + question. For example:

+
+// Make sure list<int> has bidirectional iterators.
+BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator>));
 
+

Prev: Concept Checking + Introduction
+ Next: Creating Concept Checking + Classes

+
-As an example of using BOOST_CLASS_REQUIRE 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<AssignableConcept<T> > at the top -of the definition for std::vector. + + + -
-  namespace std {
-    template <class T>
-    struct vector {
-      BOOST_CLASS_REQUIRE(T, boost, AssignableConcept);
-      ...
-    };
-  }
-
- - -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 -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. - -

-Prev: Concept Checking Introduction
-Next: Creating Concept Checking Classes - -
-


-
Copyright © 2000
- -
Copyright © 2000 -Jeremy Siek(jsiek@osl.iu.edu) -Andrew Lumsdaine(lums@osl.iu.edu) -
- - - + Jeremy Siek(jsiek@osl.iu.edu) Andrew + Lumsdaine(lums@osl.iu.edu), 2007 + David Abrahams. + + + + diff --git a/where.cpp b/where.cpp new file mode 100755 index 0000000..dfbfd02 --- /dev/null +++ b/where.cpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include +#undef NDEBUG +#include "fake_sort.hpp" + +int main() +{ + std::vector v; + fake::sort(v.begin(), v.end()); + return 0; +} diff --git a/where_fail.cpp b/where_fail.cpp new file mode 100755 index 0000000..e56b40f --- /dev/null +++ b/where_fail.cpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include +#undef NDEBUG +#include "fake_sort.hpp" + +int main() +{ + std::list v; + fake::sort(v.begin(), v.end()); + return 0; +} From 29f82069d9032064691433481cf7cedea30988a0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 10 Feb 2008 16:39:38 +0000 Subject: [PATCH 10/31] Merged revisions 43206,43208-43213 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line Fix some broken links. ........ r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line Link to people pages on the website, as they've been removed from the download. ........ r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line Point links to the pages that used to be in 'more' to the site. ........ r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line Fix links on the home page as well. ........ r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line Generated documentation which is no longer generated. ........ [SVN r43214] --- bibliography.htm | 2 +- concept_check.htm | 12 ++++++------ concept_covering.htm | 2 +- creating_concepts.htm | 4 ++-- implementation.htm | 2 +- prog_with_concepts.htm | 2 +- reference.htm | 2 +- using_concept_check.htm | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bibliography.htm b/bibliography.htm index 2c42925..4fcc8fe 100644 --- a/bibliography.htm +++ b/bibliography.htm @@ -56,7 +56,7 @@ A. A. Stepanov and M. Lee
Copyright © 2000 -Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu)
diff --git a/concept_check.htm b/concept_check.htm index 0f70167..9ddcf8d 100644 --- a/concept_check.htm +++ b/concept_check.htm @@ -26,7 +26,7 @@
The Concept Check library allows one to add explicit statement and checking of concepts in the style + "http://www.boost.org/more/generic_programming.html#concept">concepts in the style of the proposed C++ language extension. @@ -36,7 +36,7 @@

Generic programming in C++ is characterized by the use of template parameters to represent abstract data types (or “concepts”). However, the + "http://www.boost.org/more/generic_programming.html#concept">concepts”). However, the C++ language itself does not provide a mechanism for the writer of a class or function template to explicitly state the concept that the user-supplied template argument should model (or conform to). Template parameters are @@ -124,9 +124,9 @@

  • Reference
  • -

    Jeremy Siek contributed this - library. Beman Dawes managed - the formal review. Dave +

    Jeremy Siek contributed this + library. Beman Dawes managed + the formal review. Dave Abrahams contributed a rewrite that updated syntax to be more compatible with proposed syntax for concept support the C++ core language.

    @@ -319,7 +319,7 @@ boost/concept_check.hpp:236: error: no match for ‘operator<’ in ‘((boos Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/concept_covering.htm b/concept_covering.htm index 96c3208..d3997e1 100644 --- a/concept_covering.htm +++ b/concept_covering.htm @@ -115,7 +115,7 @@ public: Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/creating_concepts.htm b/creating_concepts.htm index f6cca8f..d579aaf 100644 --- a/creating_concepts.htm +++ b/creating_concepts.htm @@ -76,7 +76,7 @@ struct InputIterator InputIterator concept.

    Next, we declare the concept's associated types + "http://www.boost.org/more/generic_programming.html#associated_type">associated types as member typedefs. The associated difference type is required to be a signed integer, and the iterator category has to be convertible to std::input_iterator_tag, so we assert those relationships. The syntax for @@ -147,7 +147,7 @@ BOOST_CONCEPT_USAGE(InputIterator) Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/implementation.htm b/implementation.htm index 6df94ca..008fbed 100644 --- a/implementation.htm +++ b/implementation.htm @@ -195,7 +195,7 @@ type. Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/prog_with_concepts.htm b/prog_with_concepts.htm index 2aa9e22..fb04aed 100644 --- a/prog_with_concepts.htm +++ b/prog_with_concepts.htm @@ -134,7 +134,7 @@ amount of flexibility within which to work. Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/reference.htm b/reference.htm index 0e1797b..a8a2aa0 100644 --- a/reference.htm +++ b/reference.htm @@ -398,7 +398,7 @@ BOOST_CLASS_REQUIRES4(type1, type2, type3, type4, Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. diff --git a/using_concept_check.htm b/using_concept_check.htm index 3dc311d..ba75282 100644 --- a/using_concept_check.htm +++ b/using_concept_check.htm @@ -176,7 +176,7 @@ BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator> Copyright © 2000 - Jeremy Siek(Jeremy Siek(jsiek@osl.iu.edu) Andrew Lumsdaine(lums@osl.iu.edu), 2007 David Abrahams. From b15e7d804bc585086aa78fe48b2772839983aab2 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Wed, 26 Mar 2008 16:59:45 +0000 Subject: [PATCH 11/31] Merge changeset 43861, fixing #1716 [SVN r43870] --- include/boost/concept/requires.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) mode change 100755 => 100644 include/boost/concept/requires.hpp diff --git a/include/boost/concept/requires.hpp b/include/boost/concept/requires.hpp old mode 100755 new mode 100644 index 5570b64..024ba74 --- a/include/boost/concept/requires.hpp +++ b/include/boost/concept/requires.hpp @@ -4,6 +4,7 @@ #ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP # define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP +# include # include # include # include @@ -38,8 +39,11 @@ struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type # endif }; - -#define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_::value) +# if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010)) +# define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_::value) +# else +# define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_::value) +# endif #if defined(NDEBUG) || BOOST_WORKAROUND(BOOST_MSVC, < 1300) From 3dcaf09ecf2110eda24385e674cfd9a6c2cd85c7 Mon Sep 17 00:00:00 2001 From: Stephan Diederich Date: Mon, 17 Nov 2008 09:57:04 +0000 Subject: [PATCH 12/31] merged warning fixes from trunk (-r41358:49813) [SVN r49814] --- include/boost/concept_check.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp index 4e9fddf..12ec2ad 100644 --- a/include/boost/concept_check.hpp +++ b/include/boost/concept_check.hpp @@ -144,6 +144,8 @@ namespace boost void const_constraints(const TT& b) { #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL a = b; // const required for argument to assignment +#else + ignore_unused_variable_warning(b); #endif } private: @@ -169,6 +171,11 @@ namespace boost TT b; }; +#if (defined _MSC_VER) +# pragma warning( push ) +# pragma warning( disable : 4510 ) // default constructor could not be generated +# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required +#endif // The SGI STL version of Assignable requires copy constructor and operator= BOOST_concept(SGIAssignable,(TT)) { @@ -190,6 +197,9 @@ namespace boost } TT a; }; +#if (defined _MSC_VER) +# pragma warning( pop ) +#endif BOOST_concept(Convertible,(X)(Y)) { From 2fbf9d137577ef6ea0fd87003fe987fc234c41d6 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 24 Jan 2009 18:57:20 +0000 Subject: [PATCH 13/31] merge of cmake build files from trunk per beman [SVN r50756] --- CMakeLists.txt | 23 +++++++++++++++++++++++ module.cmake | 1 + test/CMakeLists.txt | 8 ++++++++ 3 files changed, 32 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 module.cmake create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3190d9d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +#---------------------------------------------------------------------------- +# This file was automatically generated from the original CMakeLists.txt file +# Add a variable to hold the headers for the library +set (lib_headers + concept_check.hpp + concept_archetype.hpp + concept_check +) + +# Add a library target to the build system +boost_library_project( + concept_check + # SRCDIRS + TESTDIRS test + HEADERS ${lib_headers} + # DOCDIRS + DESCRIPTION "Tools for generic programming." + MODULARIZED + AUTHORS "Jeremy Siek " + # MAINTAINERS +) + + diff --git a/module.cmake b/module.cmake new file mode 100644 index 0000000..7deef63 --- /dev/null +++ b/module.cmake @@ -0,0 +1 @@ +boost_module(concept_check DEPENDS preprocessor) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..2a85231 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,8 @@ +boost_additional_test_dependencies(concept_check BOOST_DEPENDS utility) + +# this fails but looks like it isn't the build +# boost_test_run(../stl_concept_covering) +boost_test_run(concept_check_test ../concept_check_test.cpp) +boost_test_run(class_concept_check_test ../class_concept_check_test.cpp) +boost_test_compile_fail(concept_check_fail_expected ../concept_check_fail_expected.cpp) +boost_test_compile_fail(class_concept_fail_expected ../class_concept_fail_expected.cpp) From 2c2d72087497bc8c728e383b9aba9211456ee403 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Mon, 23 Feb 2009 18:39:32 +0000 Subject: [PATCH 14/31] Merge PDF build changes from Trunk. [SVN r51417] --- doc/Jamfile.v2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 7b00065..f69d0b5 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,4 +1,7 @@ project boost/concepts ; import boostbook : boostbook ; -boostbook concepts : reference/concepts.xml ; +boostbook concepts : reference/concepts.xml + : + pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html + ; From 8842c10761bb37a061fe5a8ce0f3a632bf200c17 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 22 Mar 2009 10:42:48 +0000 Subject: [PATCH 15/31] Merge misc. changes from trunk, mostly minor documentation fixes. Merged revisions 48412,50921,51042,51369,51386-51387,51506-51507,51668,51802,51804,51881 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r48412 | danieljames | 2008-08-28 11:23:33 +0100 (Thu, 28 Aug 2008) | 1 line Fix a typo. Thanks to Jon Biggar. ........ r50921 | danieljames | 2009-01-31 09:36:38 +0000 (Sat, 31 Jan 2009) | 1 line Remove executable flag from preprocess.cmd. It was a mistake to add it. ........ r51042 | danieljames | 2009-02-06 00:04:44 +0000 (Fri, 06 Feb 2009) | 1 line Ignore some version control files in inspect. ........ r51369 | danieljames | 2009-02-21 18:49:48 +0000 (Sat, 21 Feb 2009) | 1 line Minor markup fix in concept check documentation. ........ r51386 | danieljames | 2009-02-22 11:53:28 +0000 (Sun, 22 Feb 2009) | 1 line Add index.html file for compose, as our server setup doesn't support index.htm files. ........ r51387 | danieljames | 2009-02-22 11:53:48 +0000 (Sun, 22 Feb 2009) | 5 lines Add missing index.html file for MPI and GIL. All the top level libraries now have index.html files but several sub-libraries don't. I'm not sure it's worth adding them as many of them don't have appropriate subdirectories anyway. ........ r51506 | danieljames | 2009-03-01 14:16:00 +0000 (Sun, 01 Mar 2009) | 1 line Update links to command line invocation. ........ r51507 | danieljames | 2009-03-01 14:16:24 +0000 (Sun, 01 Mar 2009) | 1 line Use xpointer attributes in the boost build documentation. ........ r51668 | danieljames | 2009-03-09 20:56:51 +0000 (Mon, 09 Mar 2009) | 1 line Redirect to the Trac wiki instead of the old one. ........ r51802 | danieljames | 2009-03-16 20:21:05 +0000 (Mon, 16 Mar 2009) | 1 line Use paragraphs inside purpose tags. ........ r51804 | danieljames | 2009-03-16 20:21:46 +0000 (Mon, 16 Mar 2009) | 1 line Give the variablelist a margin. ........ r51881 | danieljames | 2009-03-21 15:35:35 +0000 (Sat, 21 Mar 2009) | 1 line Fix html. ........ [SVN r51897] --- doc/reference/concepts.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/reference/concepts.xml b/doc/reference/concepts.xml index bd7cce0..feb41de 100644 --- a/doc/reference/concepts.xml +++ b/doc/reference/concepts.xml @@ -51,7 +51,7 @@ and Boost Graph and Property Map documentation, the SGI Standard Template Library documentation and the Hewlett-Packard STL, under the following license: -

    Permission to use, copy, modify, distribute and +
    Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appears in all copies and that both that copyright @@ -59,7 +59,7 @@ documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied - warranty.
    + warranty.
    Concept reference From 533211c4ad3cada197af386cb3d094918d2ef220 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Wed, 22 Jul 2009 21:51:01 +0000 Subject: [PATCH 16/31] Add basic copyright/license to keep cmake out of the inspection report [SVN r55095] --- CMakeLists.txt | 6 ++++++ test/CMakeLists.txt | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3190d9d..073ef90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #---------------------------------------------------------------------------- # This file was automatically generated from the original CMakeLists.txt file # Add a variable to hold the headers for the library diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2a85231..fea159f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# boost_additional_test_dependencies(concept_check BOOST_DEPENDS utility) # this fails but looks like it isn't the build From 2d21b2041f56f5e9d9bb4c1600c3dd4884000c29 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 26 Jul 2009 20:11:03 +0000 Subject: [PATCH 17/31] Add boost license info to documentation for a few libraries. Merged revisions 55098 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r55098 | danieljames | 2009-07-22 23:35:08 +0100 (Wed, 22 Jul 2009) | 8 lines Add boost license info to documentation for a few libraries. * Boost.Any: Kevlin Henney is in blanket-permission.txt * Boost.Variant: Eric Friedman and Itay Maman are both in blanket-permissions.txt * Boost.Concept: Idiana University, University of Notre Dame du Lac, Jeremy Siek, Lie-Quan Lee, Andrew Lumsdaine are all listed under blanket permissions. SGI and HP aren't so their license is left alone. ........ [SVN r55188] --- doc/reference/concepts.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/reference/concepts.xml b/doc/reference/concepts.xml index feb41de..ffe32c1 100644 --- a/doc/reference/concepts.xml +++ b/doc/reference/concepts.xml @@ -38,6 +38,12 @@ + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) + + This product includes software developed at the University of Notre Dame and the Pervasive Technology Labs at Indiana University. For technical information contact Andrew Lumsdaine From 199cb1692b7b389733571ae6a2cd43faed5594fa Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 4 Oct 2009 10:31:47 +0000 Subject: [PATCH 18/31] Fixed more links to property_map. Merged revisions 53478 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r53478 | jewillco | 2009-05-31 02:48:28 +0100 (Sun, 31 May 2009) | 1 line Fixed more links to property_map ........ [SVN r56569] --- using_concept_check.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/using_concept_check.htm b/using_concept_check.htm index ba75282..2d08db2 100644 --- a/using_concept_check.htm +++ b/using_concept_check.htm @@ -32,7 +32,7 @@ complete list. In addition, other boost libraries come with concept checking classes for the concepts that are particular to those libraries. For example, there are graph - concepts and property map + concepts and property map concepts. Also, whenever anyone writing function templates needs to express requirements that are not yet stated by an existing concept, a new concept checking class should be created. How to do this is explained @@ -136,7 +136,7 @@ BOOST_CONCEPT_REQUIRES( corresponding concept checking class will have multiple template parameters. The following example shows how BOOST_CONCEPT_REQUIRES is used with the ReadWritePropertyMap + "../property_map/doc/ReadWritePropertyMap.html">ReadWritePropertyMap concept, which takes two type parameters: a property map and the key type for the map.

    
    From 08250885bfb64079e50b5943af459143519c25b3 Mon Sep 17 00:00:00 2001
    From: "Troy D. Straszheim" 
    Date: Sat, 17 Oct 2009 01:10:45 +0000
    Subject: [PATCH 19/31] rm cmake from the release branch before it goes out
     broken.  Policy dictates that you never commit to release, you commit to
     trunk and merge to release.
    
    [SVN r56941]
    ---
     CMakeLists.txt      | 29 -----------------------------
     module.cmake        |  1 -
     test/CMakeLists.txt | 14 --------------
     3 files changed, 44 deletions(-)
     delete mode 100644 CMakeLists.txt
     delete mode 100644 module.cmake
     delete mode 100644 test/CMakeLists.txt
    
    diff --git a/CMakeLists.txt b/CMakeLists.txt
    deleted file mode 100644
    index 073ef90..0000000
    --- a/CMakeLists.txt
    +++ /dev/null
    @@ -1,29 +0,0 @@
    -#
    -# Copyright Troy D. Straszheim
    -#
    -# Distributed under the Boost Software License, Version 1.0.
    -# See http://www.boost.org/LICENSE_1_0.txt
    -#
    -#----------------------------------------------------------------------------
    -# This file was automatically generated from the original CMakeLists.txt file
    -# Add a variable to hold the headers for the library
    -set (lib_headers
    -    concept_check.hpp
    -    concept_archetype.hpp
    -    concept_check
    -)
    -
    -# Add a library target to the build system
    -boost_library_project(
    -  concept_check
    -  #  SRCDIRS 
    -  TESTDIRS  test
    -  HEADERS ${lib_headers}
    -  #  DOCDIRS 
    -  DESCRIPTION  "Tools for generic programming."
    -  MODULARIZED 
    -  AUTHORS  "Jeremy Siek "
    -  #  MAINTAINERS 
    -)
    -
    -
    diff --git a/module.cmake b/module.cmake
    deleted file mode 100644
    index 7deef63..0000000
    --- a/module.cmake
    +++ /dev/null
    @@ -1 +0,0 @@
    -boost_module(concept_check DEPENDS preprocessor)
    \ No newline at end of file
    diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
    deleted file mode 100644
    index fea159f..0000000
    --- a/test/CMakeLists.txt
    +++ /dev/null
    @@ -1,14 +0,0 @@
    -#
    -# Copyright Troy D. Straszheim
    -#
    -# Distributed under the Boost Software License, Version 1.0.
    -# See http://www.boost.org/LICENSE_1_0.txt
    -#
    -boost_additional_test_dependencies(concept_check BOOST_DEPENDS utility)
    -
    -# this fails but looks like it isn't the build
    -# boost_test_run(../stl_concept_covering)
    -boost_test_run(concept_check_test ../concept_check_test.cpp)
    -boost_test_run(class_concept_check_test ../class_concept_check_test.cpp)
    -boost_test_compile_fail(concept_check_fail_expected ../concept_check_fail_expected.cpp)
    -boost_test_compile_fail(class_concept_fail_expected ../class_concept_fail_expected.cpp)
    
    From 1f226e2dc9af4c6c9f017533c40160ce088425ad Mon Sep 17 00:00:00 2001
    From: John Maddock 
    Date: Thu, 4 Mar 2010 18:03:05 +0000
    Subject: [PATCH 20/31] Fixes #3980.
    
    [SVN r60151]
    ---
     include/boost/concept/detail/has_constraints.hpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
     mode change 100755 => 100644 include/boost/concept/detail/has_constraints.hpp
    
    diff --git a/include/boost/concept/detail/has_constraints.hpp b/include/boost/concept/detail/has_constraints.hpp
    old mode 100755
    new mode 100644
    index 3112b55..9191181
    --- a/include/boost/concept/detail/has_constraints.hpp
    +++ b/include/boost/concept/detail/has_constraints.hpp
    @@ -19,7 +19,7 @@ namespace detail
       template 
       struct wrap_constraints {};
         
    -#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
    +#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__)
       // Work around the following bogus error in Sun Studio 11, by
       // turning off the has_constraints function entirely:
       //    Error: complex expression not allowed in dependent template
    
    From def441d02daf62d4fb14b8acef175bde4e637fc6 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= 
    Date: Sun, 11 Apr 2010 15:52:27 +0000
    Subject: [PATCH 21/31] Merged revisions 61152,61185 via svnmerge from
     https://svn.boost.org/svn/boost/trunk
    
    ........
      r61152 | jhunold | 2010-04-09 11:04:51 +0200 (Fr, 09 Apr 2010) | 2 lines
    
      Silence gcc warnings when using UnaryFunction with reference parameters.
    ........
      r61185 | jhunold | 2010-04-10 19:50:26 +0200 (Sa, 10 Apr 2010) | 2 lines
    
      Dummy-Constructor only for gcc > 4.
    ........
    
    
    [SVN r61205]
    ---
     include/boost/concept_check.hpp | 11 ++++++++++-
     1 file changed, 10 insertions(+), 1 deletion(-)
    
    diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
    index 12ec2ad..7ee3036 100644
    --- a/include/boost/concept_check.hpp
    +++ b/include/boost/concept_check.hpp
    @@ -330,7 +330,16 @@ namespace boost
           {
               f(arg);
           }
    -      
    +
    +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
    +                      && BOOST_WORKAROUND(__GNUC__, > 3)))
    +      // Declare a dummy construktor to make gcc happy.
    +      // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
    +      // (warning: non-static reference "const double& boost::UnaryFunction::arg"
    +      // in class without a constructor [-Wuninitialized])
    +      UnaryFunction();
    +#endif
    +
           Func f;
           Arg arg;
       };
    
    From 570d5a6f92d7b44fd75c1bc554fa49e5a7eee309 Mon Sep 17 00:00:00 2001
    From: Jeremiah Willcock 
    Date: Tue, 8 Jun 2010 19:31:13 +0000
    Subject: [PATCH 22/31] Merged r53751, r41955, r47793, r47794, r47797, r62595
     from trunk; fixes #865
    
    [SVN r62596]
    ---
     concept_check.htm                             |  2 +-
     .../concept/detail/backward_compatibility.hpp | 16 ++++++++++
     include/boost/concept/detail/borland.hpp      |  5 +--
     include/boost/concept/detail/general.hpp      | 21 ++++++++----
     .../boost/concept/detail/has_constraints.hpp  |  6 ++--
     include/boost/concept/detail/msvc.hpp         | 32 ++++++++++++++++---
     include/boost/concept/usage.hpp               |  9 +++---
     stl_concept_check.cpp                         |  3 +-
     8 files changed, 73 insertions(+), 21 deletions(-)
     create mode 100644 include/boost/concept/detail/backward_compatibility.hpp
     mode change 100755 => 100644 include/boost/concept/detail/borland.hpp
     mode change 100755 => 100644 include/boost/concept/detail/general.hpp
     mode change 100755 => 100644 include/boost/concept/detail/msvc.hpp
     mode change 100755 => 100644 include/boost/concept/usage.hpp
    
    diff --git a/concept_check.htm b/concept_check.htm
    index 9ddcf8d..1dd72c2 100644
    --- a/concept_check.htm
    +++ b/concept_check.htm
    @@ -250,7 +250,7 @@ bad_error_eg.cpp:8:   instantiated from here
     boost/concept_check.hpp: In destructor ‘boost::LessThanComparable<TT>::~
       LessThanComparable() [with TT = std::complex<float>]’:
     boost/concept/detail/general.hpp:29:   instantiated from ‘static void boost::
    -  concept::requirement<Model>::failed() [with Model = boost::
    +  concepts::requirement<Model>::failed() [with Model = boost::
       LessThanComparable<std::complex<float> >]’
     boost/concept/requires.hpp:30:   instantiated from ‘boost::_requires_<void
       (*)(boost::LessThanComparable<std::complex<float> >)>’
    diff --git a/include/boost/concept/detail/backward_compatibility.hpp b/include/boost/concept/detail/backward_compatibility.hpp
    new file mode 100644
    index 0000000..88d5921
    --- /dev/null
    +++ b/include/boost/concept/detail/backward_compatibility.hpp
    @@ -0,0 +1,16 @@
    +// Copyright David Abrahams 2009. Distributed under the Boost
    +// Software License, Version 1.0. (See accompanying
    +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
    +#ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
    +# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
    +
    +namespace boost
    +{
    +  namespace concepts {}
    +
    +# if !defined(BOOST_NO_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD)
    +  namespace concept = concepts;
    +# endif 
    +} // namespace boost::concept
    +
    +#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
    diff --git a/include/boost/concept/detail/borland.hpp b/include/boost/concept/detail/borland.hpp
    old mode 100755
    new mode 100644
    index 59fec55..300d5d4
    --- a/include/boost/concept/detail/borland.hpp
    +++ b/include/boost/concept/detail/borland.hpp
    @@ -5,8 +5,9 @@
     # define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
     
     # include 
    +# include 
     
    -namespace boost { namespace concept {
    +namespace boost { namespace concepts {
     
     template 
     struct require;
    @@ -21,7 +22,7 @@ struct require
       enum                                                  \
       {                                                     \
           BOOST_PP_CAT(boost_concept_check,__LINE__) =      \
    -      boost::concept::require::instantiate  \
    +      boost::concepts::require::instantiate  \
       }
     
     }} // namespace boost::concept
    diff --git a/include/boost/concept/detail/general.hpp b/include/boost/concept/detail/general.hpp
    old mode 100755
    new mode 100644
    index f36f9c4..e3014c1
    --- a/include/boost/concept/detail/general.hpp
    +++ b/include/boost/concept/detail/general.hpp
    @@ -5,6 +5,7 @@
     # define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
     
     # include 
    +# include 
     
     # ifdef BOOST_OLD_CONCEPT_SUPPORT
     #  include 
    @@ -13,7 +14,7 @@
     
     // This implementation works on Comeau and GCC, all the way back to
     // 2.95
    -namespace boost { namespace concept {
    +namespace boost { namespace concepts {
     
     template 
     struct requirement_;
    @@ -29,6 +30,14 @@ struct requirement
         static void failed() { ((Model*)0)->~Model(); }
     };
     
    +struct failed {};
    +
    +template 
    +struct requirement
    +{
    +    static void failed() { ((Model*)0)->~Model(); }
    +};
    +
     # ifdef BOOST_OLD_CONCEPT_SUPPORT
     
     template 
    @@ -40,9 +49,9 @@ struct constraint
     template 
     struct requirement_
       : mpl::if_<
    -        concept::not_satisfied
    +        concepts::not_satisfied
           , constraint
    -      , requirement
    +      , requirement
         >::type
     {};
       
    @@ -51,14 +60,14 @@ struct requirement_
     // For GCC-2.x, these can't have exactly the same name
     template 
     struct requirement_
    -  : requirement
    +    : requirement
     {};
       
     # endif
     
     #  define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr )             \
    -    typedef ::boost::concept::detail::instantiate<          \
    -    &::boost::concept::requirement_::failed>    \
    +    typedef ::boost::concepts::detail::instantiate<          \
    +    &::boost::concepts::requirement_::failed>    \
           BOOST_PP_CAT(boost_concept_check,__LINE__)
     
     }}
    diff --git a/include/boost/concept/detail/has_constraints.hpp b/include/boost/concept/detail/has_constraints.hpp
    index 9191181..a309db3 100644
    --- a/include/boost/concept/detail/has_constraints.hpp
    +++ b/include/boost/concept/detail/has_constraints.hpp
    @@ -6,7 +6,9 @@
     
     # include 
     # include 
    -namespace boost { namespace concept {
    +# include 
    +
    +namespace boost { namespace concepts {
     
     namespace detail
     { 
    @@ -43,6 +45,6 @@ struct not_satisfied
         typedef mpl::bool_ type;
     };
     
    -}} // namespace boost::concept::detail
    +}} // namespace boost::concepts::detail
     
     #endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
    diff --git a/include/boost/concept/detail/msvc.hpp b/include/boost/concept/detail/msvc.hpp
    old mode 100755
    new mode 100644
    index 3aadb79..9fbd250
    --- a/include/boost/concept/detail/msvc.hpp
    +++ b/include/boost/concept/detail/msvc.hpp
    @@ -5,6 +5,7 @@
     # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
     
     # include 
    +# include 
     
     # ifdef BOOST_OLD_CONCEPT_SUPPORT
     #  include 
    @@ -12,7 +13,8 @@
     # endif
     
     
    -namespace boost { namespace concept {
    +namespace boost { namespace concepts {
    +
     
     template 
     struct check
    @@ -22,7 +24,19 @@ struct check
             x->~Model();
         }
     };
    -  
    +
    +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
    +struct failed {};
    +template 
    +struct check
    +{
    +    virtual void failed(Model* x)
    +    {
    +        x->~Model();
    +    }
    +};
    +# endif
    +
     # ifdef BOOST_OLD_CONCEPT_SUPPORT
       
     namespace detail
    @@ -38,7 +52,11 @@ struct require
       : mpl::if_c<
             not_satisfied::value
           , detail::constraint
    +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
           , check
    +# else
    +      , check
    +# endif 
             >::type
     {};
           
    @@ -46,7 +64,11 @@ struct require
       
     template 
     struct require
    -  : check
    +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
    +    : check
    +# else
    +    : check
    +# endif 
     {};
       
     # endif
    @@ -70,7 +92,7 @@ struct require
     enum                                                \
     {                                                   \
         BOOST_PP_CAT(boost_concept_check,__LINE__) =    \
    -    sizeof(::boost::concept::require)    \
    +    sizeof(::boost::concepts::require)    \
     }
       
     # else // Not vc-7.1
    @@ -83,7 +105,7 @@ require_(void(*)(Model));
     enum                                                    \
     {                                                       \
         BOOST_PP_CAT(boost_concept_check,__LINE__) =        \
    -      sizeof(::boost::concept::require_((ModelFnPtr)0)) \
    +      sizeof(::boost::concepts::require_((ModelFnPtr)0)) \
     }
       
     # endif
    diff --git a/include/boost/concept/usage.hpp b/include/boost/concept/usage.hpp
    old mode 100755
    new mode 100644
    index 9af8ca3..21547c3
    --- a/include/boost/concept/usage.hpp
    +++ b/include/boost/concept/usage.hpp
    @@ -6,8 +6,9 @@
     
     # include 
     # include 
    +# include 
     
    -namespace boost { namespace concept { 
    +namespace boost { namespace concepts { 
     
     # if BOOST_WORKAROUND(__GNUC__, == 2)
     
    @@ -25,19 +26,19 @@ struct usage_requirements
     
     #   define BOOST_CONCEPT_USAGE(model)                                    \
           model(); /* at least 2.96 and 3.4.3 both need this :( */           \
    -      BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \
    +      BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \
           ~model()
     
     #  else
     
     #   define BOOST_CONCEPT_USAGE(model)                                    \
    -      BOOST_CONCEPT_ASSERT((boost::concept::usage_requirements)); \
    +      BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \
           ~model()
     
     #  endif
     
     # endif 
     
    -}} // namespace boost::concept
    +}} // namespace boost::concepts
     
     #endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP
    diff --git a/stl_concept_check.cpp b/stl_concept_check.cpp
    index 8ec6f96..d336de1 100644
    --- a/stl_concept_check.cpp
    +++ b/stl_concept_check.cpp
    @@ -47,7 +47,8 @@ main()
       function_requires< BackInsertionSequence >();
     
     #if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS))
    -#if !(defined(__sgi) && defined(BOOST_HIDE_EXPECTED_ERRORS))
    +#if !((defined(__sgi) || (defined(__DECCXX) && defined(_RWSTD_VER) && _RWSTD_VER <= 0x0203)) \
    +  && defined(BOOST_HIDE_EXPECTED_ERRORS))
       // old deque iterator missing n + iter operation
       function_requires< Mutable_RandomAccessContainer >();
     #endif
    
    From 45d722b5c30cf07ec1ab70f0d2b954795b741d00 Mon Sep 17 00:00:00 2001
    From: Daniel James 
    Date: Sat, 26 Jun 2010 12:30:09 +0000
    Subject: [PATCH 23/31] Merge documentation fixes.
    
    * Use `doc/src/*.css` instead of `doc/html/*.css`.
    * Remove wiki and people directories.
    * Some documentation fixes.
    * Left out `minimal.css` changes and boostbook changes because of clashes.
    
    
    [SVN r63347]
    ---
     doc/Jamfile.v2 | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
    index f69d0b5..500fa14 100644
    --- a/doc/Jamfile.v2
    +++ b/doc/Jamfile.v2
    @@ -4,4 +4,5 @@ import boostbook : boostbook ;
     boostbook concepts : reference/concepts.xml 
     	:
             pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
    +        boost.root=../../../..
     	;
    
    From 807fcd7b9723c5945009e69a82c1f286a6c6dbff Mon Sep 17 00:00:00 2001
    From: Jeremiah Willcock 
    Date: Tue, 5 Oct 2010 18:15:27 +0000
    Subject: [PATCH 24/31] Merged r47768 (new example) and r62611 (fix for bug
     #4032) from trunk; refs #4032
    
    [SVN r65770]
    ---
     include/boost/concept_check.hpp | 38 +++++++++++++++++++++++++++++++++
     reference.htm                   |  4 ++++
     2 files changed, 42 insertions(+)
    
    diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
    index 7ee3036..58bd8b2 100644
    --- a/include/boost/concept_check.hpp
    +++ b/include/boost/concept_check.hpp
    @@ -1,5 +1,7 @@
     //
     // (C) Copyright Jeremy Siek 2000.
    +// Copyright 2002 The Trustees of Indiana University.
    +//
     // Distributed under the Boost Software License, Version 1.0. (See
     // accompanying file LICENSE_1_0.txt or copy at
     // http://www.boost.org/LICENSE_1_0.txt)
    @@ -999,6 +1001,42 @@ namespace boost
     
       // HashedAssociativeContainer
     
    +  BOOST_concept(Collection,(C))
    +  {
    +      BOOST_CONCEPT_USAGE(Collection)
    +      {
    +        boost::function_requires >();
    +        boost::function_requires >();
    +        boost::function_requires >();
    +        const_constraints(c);
    +        i = c.begin();
    +        i = c.end();
    +        c.swap(c);
    +      }
    +
    +      void const_constraints(const C& c) {
    +        ci = c.begin();
    +        ci = c.end();
    +        n = c.size();
    +        b = c.empty();
    +      }
    +
    +    private:
    +      typedef typename C::value_type value_type;
    +      typedef typename C::iterator iterator;
    +      typedef typename C::const_iterator const_iterator;
    +      typedef typename C::reference reference;
    +      typedef typename C::const_reference const_reference;
    +      // typedef typename C::pointer pointer;
    +      typedef typename C::difference_type difference_type;
    +      typedef typename C::size_type size_type;
    +
    +      C c;
    +      bool b;
    +      iterator i;
    +      const_iterator ci;
    +      size_type n;
    +  };
     } // namespace boost
     
     # include 
    diff --git a/reference.htm b/reference.htm
    index a8a2aa0..7c113e6 100644
    --- a/reference.htm
    +++ b/reference.htm
    @@ -279,6 +279,10 @@ struct SortedAssociativeContainer;
    +
    +template <class C>
    +struct Collection;
     

    Basic Archetype From 7dec68923ddf03a9ab8e90d7648051229a02fc70 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Sat, 8 Jan 2011 18:38:08 +0000 Subject: [PATCH 25/31] Merging fixes to release; fixes #2294 fixes #4918 fixes #3645 refs #2823 refs #1427 refs #2893 [SVN r67792] --- include/boost/concept_check.hpp | 166 ++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 64 deletions(-) diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp index 58bd8b2..01b2f4e 100644 --- a/include/boost/concept_check.hpp +++ b/include/boost/concept_check.hpp @@ -38,14 +38,14 @@ namespace boost // // Backward compatibility // - + template inline void function_requires(Model* = 0) { BOOST_CONCEPT_ASSERT((Model)); - } + } template inline void ignore_unused_variable_warning(T const&) {} - + # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ BOOST_CONCEPT_ASSERT((ns::concept)) @@ -58,20 +58,21 @@ namespace boost # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ BOOST_CONCEPT_ASSERT((ns::concept)) - + // // Begin concept definitions // BOOST_concept(Integer, (T)) { BOOST_CONCEPT_USAGE(Integer) - { + { x.error_type_must_be_an_integer_type(); } private: T x; }; + template <> struct Integer {}; template <> struct Integer {}; template <> struct Integer {}; template <> struct Integer {}; @@ -89,7 +90,7 @@ namespace boost # endif BOOST_concept(SignedInteger,(T)) { - BOOST_CONCEPT_USAGE(SignedInteger) { + BOOST_CONCEPT_USAGE(SignedInteger) { x.error_type_must_be_a_signed_integer_type(); } private: @@ -103,16 +104,16 @@ namespace boost template <> struct SignedInteger< ::boost::long_long_type> {}; # elif defined(BOOST_HAS_MS_INT64) template <> struct SignedInteger<__int64> {}; -# endif +# endif BOOST_concept(UnsignedInteger,(T)) { - BOOST_CONCEPT_USAGE(UnsignedInteger) { + BOOST_CONCEPT_USAGE(UnsignedInteger) { x.error_type_must_be_an_unsigned_integer_type(); } private: T x; }; - + template <> struct UnsignedInteger {}; template <> struct UnsignedInteger {}; template <> struct UnsignedInteger {}; @@ -138,23 +139,24 @@ namespace boost { BOOST_CONCEPT_USAGE(Assignable) { #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL - a = a; // require assignment operator + a = b; // require assignment operator #endif - const_constraints(a); + const_constraints(b); } private: - void const_constraints(const TT& b) { + void const_constraints(const TT& x) { #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL - a = b; // const required for argument to assignment + a = x; // const required for argument to assignment #else - ignore_unused_variable_warning(b); + ignore_unused_variable_warning(x); #endif } private: TT a; + TT b; }; - + BOOST_concept(CopyConstructible,(TT)) { BOOST_CONCEPT_USAGE(CopyConstructible) { @@ -182,22 +184,23 @@ namespace boost BOOST_concept(SGIAssignable,(TT)) { BOOST_CONCEPT_USAGE(SGIAssignable) { - TT b(a); + TT c(a); #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL - a = a; // require assignment operator + a = b; // require assignment operator #endif - const_constraints(a); - ignore_unused_variable_warning(b); + const_constraints(b); + ignore_unused_variable_warning(c); } private: - void const_constraints(const TT& b) { - TT c(b); + void const_constraints(const TT& x) { + TT c(x); #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL - a = b; // const required for argument to assignment + a = x; // const required for argument to assignment #endif ignore_unused_variable_warning(c); } TT a; + TT b; }; #if (defined _MSC_VER) # pragma warning( pop ) @@ -299,7 +302,7 @@ namespace boost BOOST_concept(Generator,(Func)(Return)) { BOOST_CONCEPT_USAGE(Generator) { test(is_void()); } - + private: void test(boost::mpl::false_) { @@ -312,22 +315,22 @@ namespace boost { f(); } - + Func f; }; BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) { BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } - + private: void test(boost::mpl::false_) { f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) Return r = f(arg); - ignore_unused_variable_warning(r); + ignore_unused_variable_warning(r); } - + void test(boost::mpl::true_) { f(arg); @@ -356,12 +359,21 @@ namespace boost Return r = f(first, second); // require operator() (void)r; } - + void test(boost::mpl::true_) { f(first,second); } - + +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::BinaryFunction::arg" + // in class without a constructor [-Wuninitialized]) + BinaryFunction(); +#endif + Func f; First first; Second second; @@ -373,6 +385,15 @@ namespace boost require_boolean_expr(f(arg)); // require operator() returning bool } private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::UnaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + UnaryPredicate(); +#endif + Func f; Arg arg; }; @@ -383,6 +404,14 @@ namespace boost require_boolean_expr(f(a, b)); // require operator() returning bool } private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + BinaryPredicate(); +#endif Func f; First a; Second b; @@ -392,7 +421,7 @@ namespace boost BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) : BinaryPredicate { - BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { + BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { const_constraints(f); } private: @@ -400,6 +429,15 @@ namespace boost // operator() must be a const member function require_boolean_expr(fun(a, b)); } +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::Const_BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + Const_BinaryPredicate(); +#endif + Func f; First a; Second b; @@ -409,7 +447,7 @@ namespace boost : Generator { typedef typename Func::result_type result_type; - + BOOST_CONCEPT_USAGE(AdaptableGenerator) { BOOST_CONCEPT_ASSERT((Convertible)); @@ -440,7 +478,7 @@ namespace boost typedef typename Func::first_argument_type first_argument_type; typedef typename Func::second_argument_type second_argument_type; typedef typename Func::result_type result_type; - + ~AdaptableBinaryFunction() { BOOST_CONCEPT_ASSERT((Convertible)); @@ -478,7 +516,7 @@ namespace boost { BOOST_CONCEPT_ASSERT((SignedInteger)); BOOST_CONCEPT_ASSERT((Convertible)); - + TT j(i); (void)*i; // require dereference operator ++j; // require preincrement operator @@ -492,7 +530,7 @@ namespace boost : Assignable { BOOST_CONCEPT_USAGE(OutputIterator) { - + ++i; // require preincrement operator i++; // require postincrement operator *i++ = t; // require postincrement and assignment @@ -511,11 +549,11 @@ namespace boost BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category , std::forward_iterator_tag >)); - + typename InputIterator::reference r = *i; ignore_unused_variable_warning(r); } - + private: TT i; }; @@ -577,7 +615,7 @@ namespace boost n = i - j; // require difference operator (void)i[n]; // require element access operator } - + private: TT a, b; TT i, j; @@ -615,7 +653,7 @@ namespace boost BOOST_CONCEPT_ASSERT((InputIterator)); const_constraints(c); } - + private: void const_constraints(const C& cc) { i = cc.begin(); @@ -636,19 +674,19 @@ namespace boost typedef typename C::reference reference; typedef typename C::iterator iterator; typedef typename C::pointer pointer; - + BOOST_CONCEPT_USAGE(Mutable_Container) { BOOST_CONCEPT_ASSERT(( Assignable)); - + BOOST_CONCEPT_ASSERT((InputIterator)); - + i = c.begin(); i = c.end(); c.swap(c2); } - + private: iterator i; C c, c2; @@ -664,7 +702,7 @@ namespace boost typename ForwardContainer::const_iterator >)); } - }; + }; BOOST_concept(Mutable_ForwardContainer,(C)) : ForwardContainer @@ -677,7 +715,7 @@ namespace boost typename Mutable_ForwardContainer::iterator >)); } - }; + }; BOOST_concept(ReversibleContainer,(C)) : ForwardContainer @@ -691,9 +729,9 @@ namespace boost BOOST_CONCEPT_ASSERT(( BidirectionalIterator< typename ReversibleContainer::const_iterator>)); - + BOOST_CONCEPT_ASSERT((BidirectionalIterator)); - + const_constraints(c); } private: @@ -710,17 +748,17 @@ namespace boost , ReversibleContainer { typedef typename C::reverse_iterator reverse_iterator; - + BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) { typedef typename Mutable_ForwardContainer::iterator iterator; BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); - + reverse_iterator i = c.rbegin(); i = c.rend(); } - private: + private: C c; }; @@ -736,7 +774,7 @@ namespace boost RandomAccessIterator< typename RandomAccessContainer::const_iterator >)); - + const_constraints(c); } private: @@ -745,7 +783,7 @@ namespace boost const_reference r = cc[n]; ignore_unused_variable_warning(r); } - + C c; size_type n; }; @@ -761,11 +799,11 @@ namespace boost { BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); - + typename self::reference r = c[i]; ignore_unused_variable_warning(r); } - + private: typename Mutable_ReversibleContainer::size_type i; C c; @@ -781,7 +819,7 @@ namespace boost { BOOST_CONCEPT_USAGE(Sequence) { - S + S c(n), c2(n, t), c3(first, last); @@ -806,7 +844,7 @@ namespace boost typename Sequence::const_reference r = c.front(); ignore_unused_variable_warning(r); } - + typename S::value_type t; typename S::size_type n; typename S::value_type* first, *last; @@ -865,11 +903,11 @@ namespace boost c.erase(r.first, r.second); const_constraints(c); BOOST_CONCEPT_ASSERT((BinaryPredicate)); - + typedef typename AssociativeContainer::value_type value_type_; BOOST_CONCEPT_ASSERT((BinaryPredicate)); } - + // Redundant with the base concept, but it helps below. typedef typename C::const_iterator const_iterator; private: @@ -895,7 +933,7 @@ namespace boost BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) { C c(first, last); - + pos_flag = c.insert(t); c.insert(first, last); @@ -913,7 +951,7 @@ namespace boost BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) { C c(first, last); - + pos = c.insert(t); c.insert(first, last); @@ -956,7 +994,7 @@ namespace boost { BOOST_CONCEPT_USAGE(SortedAssociativeContainer) { - C + C c(kc), c2(first, last), c3(first, last, kc); @@ -964,15 +1002,15 @@ namespace boost p = c.upper_bound(k); p = c.lower_bound(k); r = c.equal_range(k); - + c.insert(p, t); - + ignore_unused_variable_warning(c); ignore_unused_variable_warning(c2); ignore_unused_variable_warning(c3); const_constraints(c); } - + void const_constraints(const C& c) { kc = c.key_comp(); @@ -982,7 +1020,7 @@ namespace boost cp = c.lower_bound(k); cr = c.equal_range(k); } - + private: typename C::key_compare kc; typename C::value_compare vc; From a16e4a65dacc541768f96620ae1fabd5d92c341f Mon Sep 17 00:00:00 2001 From: John Maddock Date: Wed, 23 Mar 2011 12:20:49 +0000 Subject: [PATCH 26/31] Stop using BOOST_NO_CONCEPTS macro as it's going to be removed from Boost.Config. [SVN r70473] --- include/boost/concept/detail/backward_compatibility.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/concept/detail/backward_compatibility.hpp b/include/boost/concept/detail/backward_compatibility.hpp index 88d5921..66d573e 100644 --- a/include/boost/concept/detail/backward_compatibility.hpp +++ b/include/boost/concept/detail/backward_compatibility.hpp @@ -8,7 +8,7 @@ namespace boost { namespace concepts {} -# if !defined(BOOST_NO_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) +# if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) namespace concept = concepts; # endif } // namespace boost::concept From da5ab9b8076535ffd12e6f9d96329d54348cdd84 Mon Sep 17 00:00:00 2001 From: Jeremiah Willcock Date: Sun, 15 Jan 2012 23:32:09 +0000 Subject: [PATCH 27/31] Merged r76050, r75547, r75891, r76049, r76083, and r76439 from trunk (reverse_graph bug fixes and fix for #6293); refs #6293 [SVN r76535] --- reference.htm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/reference.htm b/reference.htm index 7c113e6..ae8d502 100644 --- a/reference.htm +++ b/reference.htm @@ -366,6 +366,12 @@ template <class Concept> void function_requires();

    +

    function_requires() has been deprecated in favor of BOOST_CONCEPT_ASSERT. + This means that function_requires< Concept >(); + becomes BOOST_CONCEPT_ASSERT((Concept)); + (don't forget to #include "boost/concept/assert.hpp"). + +

    Deprecated Macros

    
    From 590fed825c9ffd8bb4d3278706d908dec2c8cc86 Mon Sep 17 00:00:00 2001
    From: "Jeffrey Lee Hellrung, Jr." 
    Date: Mon, 28 May 2012 07:56:11 +0000
    Subject: [PATCH 28/31] [concept_check] "Shadowed variable warning" (fixes
     #6738)
    
    [SVN r78702]
    ---
     include/boost/concept_check.hpp | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
    index 01b2f4e..bf5a2af 100644
    --- a/include/boost/concept_check.hpp
    +++ b/include/boost/concept_check.hpp
    @@ -1052,11 +1052,11 @@ namespace boost
             c.swap(c);
           }
     
    -      void const_constraints(const C& c) {
    -        ci = c.begin();
    -        ci = c.end();
    -        n = c.size();
    -        b = c.empty();
    +      void const_constraints(const C& cc) {
    +        ci = cc.begin();
    +        ci = cc.end();
    +        n = cc.size();
    +        b = cc.empty();
           }
     
         private:
    
    From 229e3055a03210da4dd10d43bc5d26cd89267593 Mon Sep 17 00:00:00 2001
    From: Steven Watanabe 
    Date: Tue, 29 Mar 2011 15:14:53 +0000
    Subject: [PATCH 29/31] Suppress warnings on msvc 10.
    
    [SVN r70699]
    ---
     include/boost/concept_check.hpp | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
    index bf5a2af..bd1a342 100644
    --- a/include/boost/concept_check.hpp
    +++ b/include/boost/concept_check.hpp
    @@ -562,10 +562,10 @@ namespace boost
         : ForwardIterator
       {
           BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
    -        *i++ = *i;         // require postincrement and assignment
    +        *i++ = *j;         // require postincrement and assignment
           }
        private:
    -      TT i;
    +      TT i, j;
       };
     
       BOOST_concept(BidirectionalIterator,(TT))
    @@ -591,10 +591,10 @@ namespace boost
       {
           BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
           {
    -          *i-- = *i;                  // require postdecrement and assignment
    +          *i-- = *j;                  // require postdecrement and assignment
           }
        private:
    -      TT i;
    +      TT i, j;
       };
     
       BOOST_concept(RandomAccessIterator,(TT))
    
    From ccd9f52467953f4b569f52cb6a61ba6d41de09ee Mon Sep 17 00:00:00 2001
    From: Steven Watanabe 
    Date: Wed, 6 Apr 2011 22:26:42 +0000
    Subject: [PATCH 30/31] Supress msvc warnings.  Fixes #5102.
    
    [SVN r71053]
    ---
     include/boost/concept/detail/msvc.hpp |  9 +++++++++
     include/boost/concept_check.hpp       | 18 ++++++++++--------
     2 files changed, 19 insertions(+), 8 deletions(-)
    
    diff --git a/include/boost/concept/detail/msvc.hpp b/include/boost/concept/detail/msvc.hpp
    index 9fbd250..078dd22 100644
    --- a/include/boost/concept/detail/msvc.hpp
    +++ b/include/boost/concept/detail/msvc.hpp
    @@ -6,12 +6,17 @@
     
     # include 
     # include 
    +# include 
     
     # ifdef BOOST_OLD_CONCEPT_SUPPORT
     #  include 
     #  include 
     # endif
     
    +# ifdef BOOST_MSVC
    +#  pragma warning(push)
    +#  pragma warning(disable:4100)
    +# endif
     
     namespace boost { namespace concepts {
     
    @@ -111,4 +116,8 @@ enum                                                    \
     # endif
     }}
     
    +# ifdef BOOST_MSVC
    +#  pragma warning(pop)
    +# endif
    +
     #endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
    diff --git a/include/boost/concept_check.hpp b/include/boost/concept_check.hpp
    index bd1a342..9cfd281 100644
    --- a/include/boost/concept_check.hpp
    +++ b/include/boost/concept_check.hpp
    @@ -32,6 +32,12 @@
     # include 
     # include 
     
    +#if (defined _MSC_VER)
    +# pragma warning( push )
    +# pragma warning( disable : 4510 ) // default constructor could not be generated
    +# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
    +#endif
    +
     namespace boost
     {
     
    @@ -175,11 +181,6 @@ namespace boost
         TT b;
       };
     
    -#if (defined _MSC_VER)
    -# pragma warning( push )
    -# pragma warning( disable : 4510 ) // default constructor could not be generated
    -# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
    -#endif
       // The SGI STL version of Assignable requires copy constructor and operator=
       BOOST_concept(SGIAssignable,(TT))
       {
    @@ -202,9 +203,6 @@ namespace boost
         TT a;
         TT b;
       };
    -#if (defined _MSC_VER)
    -# pragma warning( pop )
    -#endif
     
       BOOST_concept(Convertible,(X)(Y))
       {
    @@ -1077,6 +1075,10 @@ namespace boost
       };
     } // namespace boost
     
    +#if (defined _MSC_VER)
    +# pragma warning( pop )
    +#endif
    +
     # include 
     
     #endif // BOOST_CONCEPT_CHECKS_HPP
    
    From b708baa8ed03a431eb37ab17a83a2e4a22d4eff6 Mon Sep 17 00:00:00 2001
    From: Peter Dimov 
    Date: Mon, 9 Jun 2014 04:29:52 +0300
    Subject: [PATCH 31/31] Remove include of
     boost/parameter/aux_/parenthesized_type.hpp.
    
    ---
     include/boost/concept/requires.hpp | 29 +++++++++++++++++++++++++----
     1 file changed, 25 insertions(+), 4 deletions(-)
    
    diff --git a/include/boost/concept/requires.hpp b/include/boost/concept/requires.hpp
    index 7a74d2f..365ce10 100644
    --- a/include/boost/concept/requires.hpp
    +++ b/include/boost/concept/requires.hpp
    @@ -5,12 +5,33 @@
     # define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
     
     # include 
    -# include 
     # include 
     # include 
     
     namespace boost { 
     
    +// unaryfunptr_arg_type from parameter/aux_/parenthesized_type.hpp
    +
    +namespace ccheck_aux {
    +
    +// A metafunction that transforms void(*)(T) -> T
    +template 
    +struct unaryfunptr_arg_type;
    +
    +template 
    +struct unaryfunptr_arg_type
    +{
    +    typedef Arg type;
    +};
    +
    +template <>
    +struct unaryfunptr_arg_type
    +{
    +    typedef void type;
    +};
    +
    +} // namespace ccheck_aux
    +
     // Template for use in handwritten assertions
     template 
     struct requires_ : More
    @@ -29,7 +50,7 @@ struct _requires_
     };
     
     template 
    -struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type
    +struct Requires_ : ::boost::ccheck_aux::unaryfunptr_arg_type
     {
     };
     
    @@ -42,7 +63,7 @@ struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type
     #if defined(NDEBUG)
     
     # define BOOST_CONCEPT_REQUIRES(models, result)                                    \
    -    typename ::boost::parameter::aux::unaryfunptr_arg_type::type
    +    typename ::boost::ccheck_aux::unaryfunptr_arg_type::type
     
     #elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
     
    @@ -50,7 +71,7 @@ struct Requires_ : ::boost::parameter::aux::unaryfunptr_arg_type
     # define BOOST_CONCEPT_REQUIRES(models, result)                                \
         ::boost::Requires_<                                                        \
           (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)),           \
    -      ::boost::parameter::aux::unaryfunptr_arg_type          \
    +      ::boost::ccheck_aux::unaryfunptr_arg_type          \
                          >::type
     
     #else