├── .appveyor.yml ├── .codecov.yml ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── bad_error_eg.cpp ├── bibliography.htm ├── build.jam ├── concept_check.htm ├── concept_covering.htm ├── creating_concepts.htm ├── doc ├── Jamfile.v2 └── reference │ ├── Assignable.xml │ ├── BidirectionalIterator.xml │ ├── CopyConstructible.xml │ ├── DefaultConstructible.xml │ ├── EqualityComparable.xml │ ├── ForwardIterator.xml │ ├── InputIterator.xml │ ├── LessThanComparable.xml │ ├── OutputIterator.xml │ ├── RandomAccessIterator.xml │ ├── SignedInteger.xml │ └── concepts.xml ├── implementation.htm ├── include └── boost │ ├── concept │ ├── assert.hpp │ ├── detail │ │ ├── backward_compatibility.hpp │ │ ├── borland.hpp │ │ ├── concept_def.hpp │ │ ├── concept_undef.hpp │ │ ├── general.hpp │ │ ├── has_constraints.hpp │ │ └── msvc.hpp │ ├── requires.hpp │ └── usage.hpp │ ├── concept_archetype.hpp │ ├── concept_check.hpp │ └── concept_check │ ├── borland.hpp │ ├── general.hpp │ ├── has_constraints.hpp │ └── msvc.hpp ├── index.html ├── meta ├── explicit-failures-markup.xml └── libraries.json ├── prog_with_concepts.htm ├── reference.htm ├── test ├── Jamfile.v2 ├── class_concept_check_test.cpp ├── class_concept_fail_expected.cpp ├── cmake_test │ ├── CMakeLists.txt │ └── main.cpp ├── concept_check_fail_expected.cpp ├── concept_check_test.cpp ├── fake_sort.hpp ├── function_requires_fail.cpp ├── old_concept_class_fail.cpp ├── old_concept_function_fail.cpp ├── old_concept_pass.cpp ├── old_concepts.hpp ├── stl_concept_check.cpp ├── stl_concept_covering.cpp ├── usage_fail.cpp ├── where.cpp └── where_fail.cpp └── using_concept_check.htm /.appveyor.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2016, 2017 Peter Dimov 2 | # Copyright 2017 - 2019 James E. King III 3 | # Copyright 2019 - 2021 Alexander Grund 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 6 | 7 | # 8 | # Generic Appveyor build script for boostorg repositories 9 | # See: https://github.com/boostorg/boost-ci/ 10 | # 11 | # Instructions for customizing this script for your library: 12 | # 13 | # 1. Customize the compilers and language levels you want. 14 | # 2. If you have more than include/, src/, test/, example/, examples/, 15 | # benchmark/ or tools/ directories, set the environment variable DEPINST. 16 | # For example if your build uses code in "bench/" and "fog/" directories: 17 | # - DEPINST: --include bench --include fog 18 | # 3. Enable pull request builds in your boostorg/ account. 19 | # 20 | # That's it - the script will do everything else for you. 21 | # 22 | 23 | version: 1.0.{build}-{branch} 24 | 25 | shallow_clone: true 26 | 27 | branches: 28 | only: 29 | - master 30 | - develop 31 | - /bugfix\/.*/ 32 | - /feature\/.*/ 33 | - /fix\/.*/ 34 | - /pr\/.*/ 35 | 36 | skip_commits: 37 | files: 38 | - LICENSE 39 | - meta/* 40 | - README.md 41 | 42 | matrix: 43 | fast_finish: false 44 | # Adding MAYFAIL to any matrix job allows it to fail but the build stays green: 45 | allow_failures: 46 | - MAYFAIL: true 47 | 48 | environment: 49 | global: 50 | B2_CI_VERSION: 1 51 | GIT_FETCH_JOBS: 4 52 | # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties 53 | # to use the default for a given environment, comment it out; recommend you build debug and release however: 54 | # on Windows it is important to exercise all the possibilities, especially shared vs static, however most 55 | # libraries that care about this exercise it in their Jamfiles... 56 | B2_ADDRESS_MODEL: 32,64 57 | B2_LINK: shared,static 58 | # B2_THREADING: threading=multi,single 59 | B2_VARIANT: release 60 | 61 | matrix: 62 | - FLAVOR: Visual Studio 2017 C++2a Strict 63 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 64 | B2_CXXFLAGS: -permissive- 65 | B2_CXXSTD: 2a 66 | B2_TOOLSET: msvc-14.1 67 | 68 | - FLAVOR: Visual Studio 2017 C++14/17 69 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 70 | B2_CXXSTD: 14,17 71 | B2_TOOLSET: msvc-14.1 72 | 73 | - FLAVOR: cygwin (32-bit) 74 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 75 | ADDPATH: C:\cygwin\bin; 76 | B2_ADDRESS_MODEL: 32 77 | B2_CXXSTD: 03,11,14,1z 78 | B2_TOOLSET: gcc 79 | 80 | - FLAVOR: cygwin (64-bit) 81 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 82 | ADDPATH: C:\cygwin64\bin; 83 | B2_ADDRESS_MODEL: 64 84 | B2_CXXSTD: 03,11,14,1z 85 | B2_TOOLSET: gcc 86 | 87 | install: 88 | - git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned 89 | # Copy ci folder if not testing Boost.CI 90 | - if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci 91 | - rmdir /s /q C:\boost-ci-cloned 92 | - ci\appveyor\install.bat 93 | 94 | build: off 95 | 96 | test_script: ci\build.bat 97 | 98 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - 2021 Alexander Grund 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 4 | # 5 | # Sample codecov configuration file. Edit as required 6 | 7 | codecov: 8 | max_report_age: off 9 | require_ci_to_pass: yes 10 | notify: 11 | # Increase this if you have multiple coverage collection jobs 12 | after_n_builds: 2 13 | wait_for_ci: yes 14 | 15 | parsers: 16 | gcov: 17 | branch_detection: 18 | conditional: yes 19 | loop: yes 20 | method: no 21 | macro: no 22 | 23 | # Change how pull request comments look 24 | comment: 25 | layout: "reach,diff,flags,files,footer" 26 | 27 | # Ignore specific files or folders. Glob patterns are supported. 28 | # See https://docs.codecov.com/docs/ignoring-paths 29 | ignore: 30 | - libs/concept_check/test/ 31 | - test/ 32 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol svneol=native#text/plain 2 | *.gitattributes text svneol=native#text/plain 3 | 4 | # Scriptish formats 5 | *.bat text svneol=native#text/plain 6 | *.bsh text svneol=native#text/x-beanshell 7 | *.cgi text svneol=native#text/plain 8 | *.cmd text svneol=native#text/plain 9 | *.js text svneol=native#text/javascript 10 | *.php text svneol=native#text/x-php 11 | *.pl text svneol=native#text/x-perl 12 | *.pm text svneol=native#text/x-perl 13 | *.py text svneol=native#text/x-python 14 | *.sh eol=lf svneol=LF#text/x-sh 15 | configure eol=lf svneol=LF#text/x-sh 16 | 17 | # Image formats 18 | *.bmp binary svneol=unset#image/bmp 19 | *.gif binary svneol=unset#image/gif 20 | *.ico binary svneol=unset#image/ico 21 | *.jpeg binary svneol=unset#image/jpeg 22 | *.jpg binary svneol=unset#image/jpeg 23 | *.png binary svneol=unset#image/png 24 | *.tif binary svneol=unset#image/tiff 25 | *.tiff binary svneol=unset#image/tiff 26 | *.svg text svneol=native#image/svg%2Bxml 27 | 28 | # Data formats 29 | *.pdf binary svneol=unset#application/pdf 30 | *.avi binary svneol=unset#video/avi 31 | *.doc binary svneol=unset#application/msword 32 | *.dsp text svneol=crlf#text/plain 33 | *.dsw text svneol=crlf#text/plain 34 | *.eps binary svneol=unset#application/postscript 35 | *.gz binary svneol=unset#application/gzip 36 | *.mov binary svneol=unset#video/quicktime 37 | *.mp3 binary svneol=unset#audio/mpeg 38 | *.ppt binary svneol=unset#application/vnd.ms-powerpoint 39 | *.ps binary svneol=unset#application/postscript 40 | *.psd binary svneol=unset#application/photoshop 41 | *.rdf binary svneol=unset#text/rdf 42 | *.rss text svneol=unset#text/xml 43 | *.rtf binary svneol=unset#text/rtf 44 | *.sln text svneol=native#text/plain 45 | *.swf binary svneol=unset#application/x-shockwave-flash 46 | *.tgz binary svneol=unset#application/gzip 47 | *.vcproj text svneol=native#text/xml 48 | *.vcxproj text svneol=native#text/xml 49 | *.vsprops text svneol=native#text/xml 50 | *.wav binary svneol=unset#audio/wav 51 | *.xls binary svneol=unset#application/vnd.ms-excel 52 | *.zip binary svneol=unset#application/zip 53 | 54 | # Text formats 55 | .htaccess text svneol=native#text/plain 56 | *.bbk text svneol=native#text/xml 57 | *.cmake text svneol=native#text/plain 58 | *.css text svneol=native#text/css 59 | *.dtd text svneol=native#text/xml 60 | *.htm text svneol=native#text/html 61 | *.html text svneol=native#text/html 62 | *.ini text svneol=native#text/plain 63 | *.log text svneol=native#text/plain 64 | *.mak text svneol=native#text/plain 65 | *.qbk text svneol=native#text/plain 66 | *.rst text svneol=native#text/plain 67 | *.sql text svneol=native#text/x-sql 68 | *.txt text svneol=native#text/plain 69 | *.xhtml text svneol=native#text/xhtml%2Bxml 70 | *.xml text svneol=native#text/xml 71 | *.xsd text svneol=native#text/xml 72 | *.xsl text svneol=native#text/xml 73 | *.xslt text svneol=native#text/xml 74 | *.xul text svneol=native#text/xul 75 | *.yml text svneol=native#text/plain 76 | boost-no-inspect text svneol=native#text/plain 77 | CHANGES text svneol=native#text/plain 78 | COPYING text svneol=native#text/plain 79 | INSTALL text svneol=native#text/plain 80 | Jamfile text svneol=native#text/plain 81 | Jamroot text svneol=native#text/plain 82 | Jamfile.v2 text svneol=native#text/plain 83 | Jamrules text svneol=native#text/plain 84 | Makefile* text svneol=native#text/plain 85 | README text svneol=native#text/plain 86 | TODO text svneol=native#text/plain 87 | 88 | # Code formats 89 | *.c text svneol=native#text/plain 90 | *.cpp text svneol=native#text/plain 91 | *.h text svneol=native#text/plain 92 | *.hpp text svneol=native#text/plain 93 | *.ipp text svneol=native#text/plain 94 | *.tpp text svneol=native#text/plain 95 | *.jam text svneol=native#text/plain 96 | *.java text svneol=native#text/plain 97 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Glen Joseph Fernandes 2 | # (glenjofe@gmail.com) 3 | # 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | cmake_minimum_required(VERSION 3.5...3.20) 8 | 9 | project(boost_concept_check VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) 10 | 11 | add_library(boost_concept_check INTERFACE) 12 | 13 | add_library(Boost::concept_check ALIAS boost_concept_check) 14 | 15 | target_include_directories(boost_concept_check INTERFACE include) 16 | 17 | target_link_libraries(boost_concept_check INTERFACE 18 | Boost::config 19 | Boost::preprocessor 20 | Boost::static_assert 21 | Boost::type_traits 22 | ) 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ConceptCheck, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), 2 | allows one to add explicit statement and checking of concepts in the style of the proposed C++ language extension. 3 | 4 | ### License 5 | 6 | Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). 7 | 8 | ### Properties 9 | 10 | * C++03 11 | * Header-only 12 | 13 | ### Build Status 14 | 15 | 16 | | Branch | GHA CI | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | 17 | | :-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | 18 | | [`master`](https://github.com/boostorg/concept_check/tree/master) | [![Build Status](https://github.com/boostorg/concept_check/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/concept_check/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/qj0837owatwej9ws/branch/master?svg=true)](https://ci.appveyor.com/project/cppalliance/concept-check/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16317/badge.svg)](https://scan.coverity.com/projects/boostorg-concept_check) | [![codecov](https://codecov.io/gh/boostorg/concept_check/branch/master/graph/badge.svg?token=4FWH598KON)](https://codecov.io/gh/boostorg/concept_check/tree/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/concept_check.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/concept_check) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://www.boost.org/development/tests/master/developer/concept_check.html) 19 | | [`develop`](https://github.com/boostorg/concept_check/tree/develop) | [![Build Status](https://github.com/boostorg/concept_check/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/concept_check/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/qj0837owatwej9ws/branch/develop?svg=true)](https://ci.appveyor.com/project/cppalliance/concept-check/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16317/badge.svg)](https://scan.coverity.com/projects/boostorg-concept_check) | [![codecov](https://codecov.io/gh/boostorg/concept_check/branch/develop/graph/badge.svg?token=4FWH598KON)](https://codecov.io/gh/boostorg/concept_check/tree/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/concept_check.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/concept_check) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://www.boost.org/development/tests/develop/developer/concept_check.html) 20 | 21 | ### Directories 22 | 23 | | Name | Purpose | 24 | | ----------- | ------------------------------ | 25 | | `doc` | documentation | 26 | | `include` | headers | 27 | | `test` | unit tests | 28 | 29 | ### More information 30 | 31 | * [Ask questions](https://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-concept_check) 32 | * [Report bugs](https://github.com/boostorg/concept_check/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. 33 | * Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). 34 | * Discussions about the library are held on the [Boost developers mailing list](https://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](https://www.boost.org/community/policy.html) before posting and add the `[concept_check]` tag at the beginning of the subject line. 35 | 36 | -------------------------------------------------------------------------------- /bad_error_eg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "algorithm" 4 | 5 | int main() 6 | { 7 | std::vector > v; 8 | std_::stable_sort(v.begin(), v.end()); 9 | } 10 | 11 | // (C) Copyright Jeremy Siek 2000. 12 | // Distributed under the Boost Software License, Version 1.0. (See 13 | // accompanying file LICENSE_1_0.txt or copy at 14 | // http://www.boost.org/LICENSE_1_0.txt) 15 | -------------------------------------------------------------------------------- /bibliography.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Boost Concept Checking Library: Bibliography 8 | 10 | C++ Boost 12 | 13 |
14 | 15 | 16 |

Bibliography

17 | 18 |
19 | 20 |

1 21 |
Andrei Alexandrescu
22 | Better Template Error Messages.
23 | C/C++ Users Journal, March, 1999. 24 | 25 | 26 |

2 27 |
Bjarne Stroustrup
28 | Design and Evolution of C++.
29 | Addison-Wesley, 1994 30 | 31 |

3 32 |
33 | M. H. Austern. 34 |
Generic Programming and the STL. 35 |
Professional computing series. Addison-Wesley, 1999. 36 | 37 |

4 38 |
39 | David R. Musser and Atul Saini 40 |
STL Tutorial and Reference Guide. 41 |
Professional computing series. Addison-Wesley, 1996. 42 | 43 |

5 44 |
45 | A. A. Stepanov and M. Lee 46 |
The Standard Template Library. 47 |
ISO Programming Language C++ Project, May 1994. 48 |
X3J16/94-0095, WG21/N0482 49 | 50 | 51 | 52 |
53 | 54 |
55 |
56 | 57 | 58 |
Copyright © 2000 59 | Jeremy Siek(jsiek@osl.iu.edu) 61 | Andrew Lumsdaine(lums@osl.iu.edu) 62 |
63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | constant boost_dependencies : 9 | /boost/config//boost_config 10 | /boost/preprocessor//boost_preprocessor 11 | /boost/static_assert//boost_static_assert 12 | /boost/type_traits//boost_type_traits ; 13 | 14 | project /boost/concept_check 15 | : common-requirements 16 | include 17 | ; 18 | 19 | explicit 20 | [ alias boost_concept_check : : : : $(boost_dependencies) ] 21 | [ alias all : boost_concept_check test ] 22 | ; 23 | 24 | call-if : boost-library concept_check 25 | ; 26 | 27 | -------------------------------------------------------------------------------- /concept_check.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | Concept Check Library 16 | 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

The Boost Concept Check Library (BCCL)

25 | 26 |
27 | The Concept Check library allows one to add explicit statement and 28 | checking of concepts in the style 30 | of the proposed 32 | C++ language extension. 33 |
34 | 35 |

Synopsis

36 | 37 |

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

48 | 49 |
    50 |
  • Compiler error messages resulting from incorrect template arguments 51 | can be particularly difficult to decipher. Often times the error does not 52 | point to the location of the template call-site, but instead exposes the 53 | internals of the template, which the user should never have to see.
  • 54 | 55 |
  • Without checking from the compiler, the documented requirements are 56 | oftentimes vague, incorrect, or nonexistent, so a user cannot know 57 | exactly what kind of arguments are expected.
  • 58 | 59 |
  • The documented concept requirements may not fully cover the 60 | needs of the actual template, meaning the user could get a compiler error 61 | even though the supplied template arguments meet the documented 62 | requirements.
  • 63 | 64 |
  • The documented concept requirements may be too stringent, requiring 65 | more than is really needed by the template.
  • 66 | 67 |
  • Concept names in code may drift out-of-sync with the documented 68 | requirements.
  • 69 |

The Boost Concept Checking Library provides: 70 | 71 |

    72 |
  • A mechanism for inserting compile-time checks on template parameters 73 | at their point of use.
  • 74 | 75 |
  • A framework for specifying concept requirements through concept 76 | checking classes.
  • 77 | 78 |
  • A mechanism for verifying that concept requirements cover the 79 | template.
  • 80 | 81 |
  • A suite of concept checking classes and archetype classes that match 82 | the concept requirements in the C++ Standard Library.
  • 83 | 84 |
  • An alternative to the use of traits classes for accessing associated 85 | types that mirrors the syntax proposed for the next C++ standard.
  • 86 |

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

88 | 89 |

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

98 | 99 |

The documentation is organized into the following sections.

100 | 101 |
    102 |
  1. Introduction
  2. 103 | 104 |
  3. Motivating Example
  4. 105 | 106 |
  5. History
  6. 107 | 108 |
  7. Publications
  8. 109 | 110 |
  9. Acknowledgements
  10. 111 | 112 |
  11. Using Concept Checks
  12. 113 | 114 |
  13. Creating Concept Checking 115 | Classes
  14. 116 | 117 |
  15. Concept Covering and 118 | Archetypes
  16. 119 | 120 |
  17. Programming With Concepts
  18. 121 | 122 |
  19. Implementation
  20. 123 | 124 |
  21. Reference
  22. 125 |
126 | 127 |

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

133 | 134 |

Introduction

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

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

153 | 154 |

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

159 | 160 |

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

164 | 165 |

Motivating 166 | Example

167 | 168 |

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

175 |
176 |   bad_error_eg.cpp:
177 | 1 #include <vector>
178 | 2 #include <complex>
179 | 3 #include <algorithm>
180 | 4 
181 | 5 int main()
182 | 6 {
183 | 7     std::vector<std::complex<float> > v;
184 | 8     std::stable_sort(v.begin(), v.end());
185 | 9 }
186 | 
187 | 188 |

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

190 |
191 |   template <class RandomAccessIterator>
192 |   void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
193 | 
194 | 195 |

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

197 |
198 | /usr/include/c++/4.1.2/bits/stl_algo.h: In function ‘void std::
199 |   __insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with 
200 |   _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
201 |   >*, std::vector<std::complex<float>, std::allocator<std::complex<
202 |   float> > > >]’:
203 | /usr/include/c++/4.1.2/bits/stl_algo.h:3066:   instantiated from ‘void 
204 |   std::__inplace_stable_sort(_RandomAccessIterator, 
205 |   _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::
206 |   __normal_iterator<std::complex<float>*, std::vector<std::complex<
207 |   float>, std::allocator<std::complex<float> > > >]’
208 | /usr/include/c++/4.1.2/bits/stl_algo.h:3776:   instantiated from ‘void 
209 |   std::stable_sort(_RandomAccessIterator, _RandomAccessIterator) [with 
210 |   _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::complex<float
211 |   >*, std::vector<std::complex<float>, std::allocator<std::complex<
212 |   float> > > >]’
213 | bad_error_eg.cpp:8:   instantiated from here
214 | /usr/include/c++/4.1.2/bits/stl_algo.h:2277: error: no match for 
215 |   ‘operator<’ in ‘__val < __first. __gnu_cxx::__normal_iterator<
216 |   _Iterator, _Container>::operator* [with _Iterator = std::complex<float
217 |   >*, _Container = std::vector<std::complex<float>, std::allocator<
218 |   std::complex<float> > >]()’
219 | 
220 | 221 |

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

226 | 227 |

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

231 | 232 |
    233 |
  1. There is no textual correlation between the error message and the 234 | documented requirements for std::stable_sort() and for LessThanComparable.
  2. 236 | 237 |
  3. The error message is overly long, listing functions internal 238 | to the STL (e.g. __insertion_sort) that the user 239 | does not (and should not!) know or care about.
  4. 240 | 241 |
  5. With so many internal library functions listed in the error message, 242 | the programmer could easily infer that the problem is in the library, 243 | rather than in his or her own code.
  6. 244 |
245 | 246 |

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

249 |
250 | boost/concept_check.hpp: In destructor ‘boost::LessThanComparable<TT>::~
251 |   LessThanComparable() [with TT = std::complex<float>]’:
252 | boost/concept/detail/general.hpp:29:   instantiated from ‘static void boost::
253 |   concepts::requirement<Model>::failed() [with Model = boost::
254 |   LessThanComparable<std::complex<float> >]’
255 | boost/concept/requires.hpp:30:   instantiated from ‘boost::_requires_<void
256 |   (*)(boost::LessThanComparable<std::complex<float> >)>’
257 | bad_error_eg.cpp:8:   instantiated from here
258 | boost/concept_check.hpp:236: error: no match for ‘operator<’ in ‘((boost::
259 |   LessThanComparable<std::complex<float> >*)this)->boost::
260 |   LessThanComparable<std::complex<float> >::a < ((boost::
261 |   LessThanComparable<std::complex<float> >*)this)->boost::
262 |   LessThanComparable<std::complex<float> >::b’
263 | 
264 | 265 |

This message rectifies several of the shortcomings of the standard error 266 | messages.

267 | 268 |
    269 |
  • The message refers explicitly to concepts that the user can look up 270 | in the STL documentation (LessThanComparable).
  • 272 | 273 |
  • The error message is now much shorter and does not reveal 274 | internal STL functions, nor indeed does it even point 275 | to std::stable_sort.
  • 276 | 277 |
  • The presence of concept_check.hpp in the error message 278 | alerts the user to the fact that the error lies in the user code and not 279 | in the library implementation.
  • 280 |
281 | 282 |

History

283 | 284 |

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

296 | 297 |

Publications

298 | 299 | 303 | 304 |

Acknowledgements

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

Next: Using Concept 315 | Checks

316 |
317 | 318 | 319 | 320 | 321 | 322 | 327 | 328 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 324 | Lumsdaine(lums@osl.iu.edu), 325 | 2007 David Abrahams. 326 |
329 | 330 | 331 | -------------------------------------------------------------------------------- /concept_covering.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | Concept Covering and Archetypes 15 | 16 | 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Concept Covering and 25 | Archetypes

26 | 27 |

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

50 |
 51 | template <class T>
 52 | class input_iterator_archetype
 53 | {
 54 | private:
 55 |   typedef input_iterator_archetype self;
 56 | public:
 57 |   typedef std::input_iterator_tag iterator_category;
 58 |   typedef T value_type;
 59 |   struct reference {
 60 |     operator const value_type&() const { return static_object<T>::get(); }
 61 |   };
 62 |   typedef const T* pointer;
 63 |   typedef std::ptrdiff_t difference_type;
 64 |   self& operator=(const self&) { return *this;  }
 65 |   bool operator==(const self&) const { return true; }
 66 |   bool operator!=(const self&) const { return true; }
 67 |   reference operator*() const { return reference(); }
 68 |   self& operator++() { return *this; }
 69 |   self operator++(int) { return *this; }
 70 | };
 71 | 
72 | 73 |

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

84 | 85 |

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

99 |
100 | {
101 |   typedef less_than_comparable_archetype< 
102 |       sgi_assignable_archetype<> > ValueType;
103 |   random_access_iterator_archetype<ValueType> ri;
104 |   std::stable_sort(ri, ri);
105 | }
106 | 
107 | 108 |

Next: Programming with 109 | Concepts
110 | Prev: Creating Concept Checking 111 | Classes
112 |


113 | 114 | 115 | 116 | 117 | 118 | 123 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 120 | Lumsdaine(lums@osl.iu.edu), 121 | 2007 David Abrahams. 122 |
124 | 125 | 126 | -------------------------------------------------------------------------------- /creating_concepts.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | Creating Concept Checking Classes 16 | 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Creating 25 | Concept Checking Classes

26 | 27 |

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

31 |
 32 | template <class X>
 33 | struct InputIterator
 34 |   : Assignable<X>, EqualityComparable<X>
 35 | {
 36 |  private:
 37 |     typedef std::iterator_traits<X> t;
 38 |  public:
 39 |     typedef typename t::value_type value_type;
 40 |     typedef typename t::difference_type difference_type;
 41 |     typedef typename t::reference reference;
 42 |     typedef typename t::pointer pointer;
 43 |     typedef typename t::iterator_category iterator_category;
 44 | 
 45 |     BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
 46 |     BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
 47 |         
 48 |     BOOST_CONCEPT_USAGE(InputIterator)
 49 |     {
 50 |         X j(i);             // require copy construction
 52 |         same_type(*i++,v);  // require postincrement-dereference returning value_type
 54 |         X& x = ++j;         // require preincrement returning X&
 56 |     }
 57 |     
 58 |  private:
 59 |     X i;
 60 |     value_type v;
 61 | 
 62 |     // Type deduction will fail unless the arguments have the same type.
 64 |     template <typename T>
 65 |     void same_type(T const&, T const&);
 66 | };
 67 | 
68 | 69 |

Walkthrough

70 | 71 |

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

77 | 78 |

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

94 | 95 |

Values for Usage Patterns Should Be Data Members

96 | 97 |

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

100 |
101 | BOOST_CONCEPT_USAGE(InputIterator)
102 | {
103 |     X i;                // create the values we need
105 |     value_type v;
106 | 
107 |     X j(i);             // require copy construction
109 |     same_type(*i++,v);  // require postincrement-dereference returning value_type
111 |     X& x = ++j;         // require preincrement returning X&
113 | }
114 | 
115 | 116 |

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

123 | 124 |

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

127 | 128 |

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

129 | 130 |

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

139 | 140 |

Next: Concept Covering and 141 | Archetypes
142 | Prev: Using Concept 143 | Checks

144 |
145 | 146 | 147 | 148 | 149 | 150 | 155 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 152 | Lumsdaine(lums@osl.iu.edu), 153 | 2007 David Abrahams. 154 |
156 | 157 | 158 | -------------------------------------------------------------------------------- /doc/Jamfile.v2: -------------------------------------------------------------------------------- 1 | project boost/concepts ; 2 | import boostbook : boostbook ; 3 | 4 | boostbook concepts : reference/concepts.xml 5 | : 6 | pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html 7 | boost.root=../../../.. 8 | ; 9 | 10 | ############################################################################### 11 | alias boostdoc ; 12 | explicit boostdoc ; 13 | alias boostrelease : concepts ; 14 | explicit boostrelease ; 15 | -------------------------------------------------------------------------------- /doc/reference/Assignable.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | The type must be a model of . 19 | 20 | 21 | Assignable types must have copy constructors, 22 | operator= for assignment, and the swap() 23 | function defined. 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Require operator= 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Require swap() function 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /doc/reference/BidirectionalIterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | The iterator type must be a model of . 21 | 22 | 23 | A bidirectional iterator is an iterator that can read through a sequence 24 | of values. It can move in either direction through the sequence, and can 25 | be either mutable (data pointed to by it can be changed) or not mutable. 26 | 27 | An iterator represents a position in a sequence. Therefore, the 28 | iterator can point into the sequence (returning a value when dereferenced 29 | and being incrementable), or be off-the-end (and not dereferenceable or 30 | incrementable). 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | The value type of the iterator 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | The category of the iterator 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | i is incrementable (not 85 | off-the-end) and some dereferenceable iterator j exists 86 | such that i == ++j 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Same as for predecrement 97 | Equivalent to {Iter j = i; --i; return j;} 98 | i is dereferenceable or 99 | off-the-end 100 | 101 | 102 | 103 | All iterator operations must take amortized constant time. 104 | 105 | 106 | 107 | &i = &(--i) 108 | 109 | 110 | 111 | i == j implies --i == --j 112 | 113 | 114 | 115 | ++i; --i; and --i; ++i; must end up with the 116 | value of i unmodified, if i both of the 117 | operations in the pair are valid. 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /doc/reference/CopyConstructible.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | The type must be a model of . 19 | 20 | 21 | Copy constructible types must be able to be constructed from another 22 | member of the type. 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Require copy constructor. 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /doc/reference/DefaultConstructible.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | The type must be a model of . 19 | 20 | DefaultConstructible objects only need to have a default 21 | constructor. 22 | 23 | 24 | 25 | 26 | 27 | 28 | Construct an instance of the type with default parameters. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /doc/reference/EqualityComparable.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | The type must be a model of 19 | . 20 | 21 | Equality Comparable types must have == and 22 | != operators. 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /doc/reference/ForwardIterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | The iterator type must be a model of . 21 | 22 | 23 | A forward iterator is an iterator that can read through a sequence of 24 | values. It is multi-pass (old values of the iterator can be 25 | re-used), and can be either mutable (data pointed to by it can be 26 | changed) or not mutable. 27 | 28 | An iterator represents a position in a sequence. Therefore, the 29 | iterator can point into the sequence (returning a value when dereferenced 30 | and being incrementable), or be off-the-end (and not dereferenceable or 31 | incrementable). 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | The value type of the iterator 41 | 42 | 43 | 44 | 45 | 46 | 51 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | The category of the iterator 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | i is incrementable (not 101 | off-the-end) 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | i is incrementable (not 116 | off-the-end) 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | i is incrementable (not 129 | off-the-end) 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | i is incrementable (not 140 | off-the-end) 141 | Equivalent to {Iter j = i; ++i; return j;} 142 | i is dereferenceable or 143 | off-the-end 144 | 145 | 146 | 147 | All iterator operations must take amortized constant time. 148 | 149 | 150 | 151 | &i = &(++i) 152 | 153 | 154 | 155 | i == j implies ++i == ++j 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /doc/reference/InputIterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | The iterator type must be a model of . 21 | 22 | 23 | An input iterator is an iterator that can read through a sequence of 24 | values. It is single-pass (old values of the iterator cannot be 25 | re-used), and read-only. 26 | 27 | An input iterator represents a position in a sequence. Therefore, the 28 | iterator can point into the sequence (returning a value when dereferenced 29 | and being incrementable), or be off-the-end (and not dereferenceable or 30 | incrementable). 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | The value type of the iterator (not necessarily what 50 | *i returns) 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | The difference type of the iterator 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | The category of the iterator 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | i is incrementable (not 113 | off-the-end) 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | i is incrementable (not 126 | off-the-end) 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | i is incrementable (not 135 | off-the-end) 136 | Equivalent to (void)(++i) 137 | i is dereferenceable or 138 | off-the-end 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | i is incrementable (not 151 | off-the-end) 152 | Equivalent to {value_type t = *i; ++i; return t;} 153 | i is dereferenceable or 154 | off-the-end 155 | 156 | 157 | 158 | All iterator operations must take amortized constant time. 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /doc/reference/LessThanComparable.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | The type must be a model of . 19 | 20 | LessThanComparable types must have <, 21 | >, <=, and >= 22 | operators. 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | Determine if one value is less than another. 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Determine if one value is less than or equal to another. 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Determine if one value is greater than another. 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Determine if one value is greater than or equal to another. 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /doc/reference/OutputIterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | The iterator type (with value type ) must be a model of . 22 | 23 | 24 | An output iterator is an iterator that can write a sequence of 25 | values. It is single-pass (old values of the iterator cannot be 26 | re-used), and write-only. 27 | 28 | An output iterator represents a position in a (possibly infinite) 29 | sequence. Therefore, the iterator can point into the sequence (returning 30 | a value when dereferenced and being incrementable), or be off-the-end 31 | (and not dereferenceable or incrementable). 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | The stated value type of the iterator (should be 57 | void for an output iterator that does not model some other 58 | iterator concept). 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | The difference type of the iterator 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | The category of the iterator 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | i is incrementable (not 117 | off-the-end) 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | i is incrementable (not 129 | off-the-end) 130 | *i may not be written to again until it has 131 | been incremented. 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | i is incrementable (not 144 | off-the-end) 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | i is incrementable (not 153 | off-the-end) 154 | Equivalent to (void)(++i) 155 | i is dereferenceable or 156 | off-the-end 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | i is incrementable (not 170 | off-the-end) 171 | Equivalent to {*i = t; ++i;} 172 | i is dereferenceable or 173 | off-the-end 174 | 175 | 176 | 177 | All iterator operations must take amortized constant time. 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /doc/reference/RandomAccessIterator.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | The iterator type must be a model of . 21 | 22 | 23 | A random access iterator is an iterator that can read through 24 | a sequence of values. It can move in either direction through the 25 | sequence (by any amount in constant time), and can be either mutable 26 | (data pointed to by it can be changed) or not mutable. 27 | 28 | An iterator represents a position in a sequence. Therefore, 29 | the iterator can point into the sequence (returning a value when 30 | dereferenced and being incrementable), or be off-the-end (and not 31 | dereferenceable or incrementable). 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | The value type of the iterator 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | The category of the iterator 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | The difference type of the iterator (measure of the number 68 | of steps between two iterators) 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Equivalent to applying i++ n times 110 | if n is positive, applying i-- 111 | -n times if n is negative, and to a null 112 | operation if n is zero. 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Equivalent to applying i++ n times 126 | if n is positive, applying i-- 127 | -n times if n is negative, and to a null 128 | operation if n is zero. 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | Equivalent to i+=(-n) 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | Equivalent to i+=(-n) 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Equivalent to {Iter j = i; j += n; return j;} 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | Equivalent to {Iter j = i; j += n; return j;} 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | Equivalent to i + n 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | Equivalent to i + n 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | Equivalent to i + (-n) 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | Equivalent to i + (-n) 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | The number of times i must be incremented (or 232 | decremented if the result is negative) to reach j. Not 233 | defined if j is not reachable from 234 | i. 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | Equivalent to *(i + n) 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | Equivalent to *(i + n) 269 | 270 | 271 | 272 | All iterator operations must take amortized constant time. 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /doc/reference/SignedInteger.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | Integer type must be a model of . 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | -------------------------------------------------------------------------------- /doc/reference/concepts.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 2001 10 | 2002 11 | Indiana University 12 | 13 | 14 | 15 | 2000 16 | 2001 17 | University of Notre Dame du Lac 18 | 19 | 20 | 21 | 2000 22 | Jeremy Siek 23 | Lie-Quan Lee 24 | Andrew Lumsdaine 25 | 26 | 27 | 28 | 1996 29 | 1997 30 | 1998 31 | 1999 32 | Silicon Graphics Computer Systems, Inc. 33 | 34 | 35 | 36 | 1994 37 | Hewlett-Packard Company 38 | 39 | 40 | 41 | Distributed under the Boost Software License, Version 1.0. 42 | (See accompanying file LICENSE_1_0.txt or copy at 43 | http://www.boost.org/LICENSE_1_0.txt) 45 | 46 | 47 | This product includes software developed at the University 48 | of Notre Dame and the Pervasive Technology Labs at Indiana 49 | University. For technical information contact Andrew Lumsdaine 50 | at the Pervasive Technology Labs at Indiana University. For 51 | administrative and license questions contact the Advanced 52 | Research and Technology Institute at 351 West 10th Street. 53 | Indianapolis, Indiana 46202, phone 317-278-4100, fax 54 | 317-274-5902. 55 | 56 | Some concepts based on versions from the MTL draft manual 57 | and Boost Graph and Property Map documentation, the SGI Standard 58 | Template Library documentation and the Hewlett-Packard STL, 59 | under the following license: 60 |
Permission to use, copy, modify, distribute and 61 | sell this software and its documentation for any purpose is 62 | hereby granted without fee, provided that the above copyright 63 | notice appears in all copies and that both that copyright 64 | notice and this permission notice appear in supporting 65 | documentation. Silicon Graphics makes no representations 66 | about the suitability of this software for any purpose. It is 67 | provided "as is" without express or implied 68 | warranty.
69 |
70 |
71 | Concept reference 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
85 | -------------------------------------------------------------------------------- /implementation.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | Concept Checking Implementation 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Warning

26 | 27 |

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

33 | 34 |

Implementation

35 | 36 |

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

56 |
 57 |   template <class RandomAccessIterator>
 58 |   void stable_sort_constraints(RandomAccessIterator i)
 59 |   {
 60 |     typename std::iterator_traits<RandomAccessIterator>
 61 |       ::difference_type n;
 62 |     i += n;  // exercise the requirements for RandomAccessIterator
 63 |     ...
 64 |   }
 65 |   template <class RandomAccessIterator>
 66 |   void stable_sort(RandomAccessIterator first, RandomAccessIterator last)
 67 |   {
 68 |     typedef void (*fptr_type)(RandomAccessIterator);
 69 |     fptr_type x = &stable_sort_constraints;
 70 |     ...
 71 |   }
 72 | 
73 | 74 |

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

85 |
 86 |   template <class Iter>
 87 |   struct RandomAccessIteratorConcept
 88 |   {
 89 |     void constraints()
 90 |     {
 91 |       i += n;
 92 |       ...
 93 |     }
 94 |     typename std::iterator_traits<RandomAccessIterator>
 95 |       ::difference_type n;
 96 |     Iter i;
 97 |     ...
 98 |   };
 99 | 
100 | 101 |

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

108 |
109 |   template <class Iter>
110 |   void stable_sort(Iter first, Iter last)
111 |   {
112 |     function_requires< RandomAccessIteratorConcept<Iter> >();
113 |     ...
114 |   }
115 | 
116 | 117 |

The definition of the function_requires() is as follows. The 118 | Concept is the concept checking class that has been instantiated 119 | with the modeling type. We assign the address of the constraints member 120 | function to the function pointer x, which causes the instantiation 121 | of the constraints function and checking of the concept's valid 122 | expressions. We then assign x to x to avoid unused 123 | variable compiler warnings, and wrap everything in a do-while loop to 124 | prevent name collisions.

125 |
126 |   template <class Concept>
127 |   void function_requires()
128 |   {
129 |     void (Concept::*x)() = BOOST_FPTR Concept::constraints;
130 |     ignore_unused_variable_warning(x);
131 |   }
132 | 
133 | 134 |

To check the type parameters of class templates, we provide the 135 | BOOST_CLASS_REQUIRE macro which can be used inside the body of a 136 | class definition (whereas function_requires() can only be used 137 | inside of a function body). This macro declares a nested class template, 138 | where the template parameter is a function pointer. We then use the nested 139 | class type in a typedef with the function pointer type of the constraint 140 | function as the template argument. We use the type_var and 141 | concept names in the nested class and typedef names to help 142 | prevent name collisions.

143 |
144 | #define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
145 |   typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
146 |   template <func##type_var##concept _Tp1> \
147 |   struct concept_checking_##type_var##concept { }; \
148 |   typedef concept_checking_##type_var##concept< \
149 |     BOOST_FPTR ns::concept<type_var>::constraints> \
150 |     concept_checking_typedef_##type_var##concept
151 | 
152 | 153 |

In addition, there are versions of BOOST_CLASS_REQUIRE that 154 | take more arguments, to handle concepts that include interactions between 155 | two or more types. BOOST_CLASS_REQUIRE was not used in the 156 | implementation of the BCCL concept checks because some compilers do not 157 | implement template parameters of function pointer type. 158 |

188 | 189 |

Next: Reference
190 | Prev: Programming With 191 | Concepts

192 |
193 | 194 | 195 | 196 | 197 | 198 | 203 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 200 | Lumsdaine(lums@osl.iu.edu), 201 | 2007 David Abrahams. 202 |
204 | 205 | 206 | -------------------------------------------------------------------------------- /include/boost/concept/assert.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP 5 | # define BOOST_CONCEPT_ASSERT_DWA2006430_HPP 6 | 7 | # include 8 | # include 9 | 10 | // The old protocol used a constraints() member function in concept 11 | // checking classes. If the compiler supports SFINAE, we can detect 12 | // that function and seamlessly support the old concept checking 13 | // classes. In this release, backward compatibility with the old 14 | // concept checking classes is enabled by default, where available. 15 | // The old protocol is deprecated, though, and backward compatibility 16 | // will no longer be the default in the next release. 17 | 18 | # if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \ 19 | && !defined(BOOST_NO_SFINAE) \ 20 | \ 21 | && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) 22 | 23 | // Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to 24 | // check for the presence of particularmember functions. 25 | 26 | # define BOOST_OLD_CONCEPT_SUPPORT 27 | 28 | # endif 29 | 30 | # ifdef BOOST_MSVC 31 | # include 32 | # elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 33 | # include 34 | # else 35 | # include 36 | # endif 37 | 38 | // Usage, in class or function context: 39 | // 40 | // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); 41 | // 42 | # define BOOST_CONCEPT_ASSERT(ModelInParens) \ 43 | BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens) 44 | 45 | #endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP 46 | -------------------------------------------------------------------------------- /include/boost/concept/detail/backward_compatibility.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2009. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP 5 | # define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP 6 | 7 | namespace boost 8 | { 9 | namespace concepts {} 10 | 11 | # if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) 12 | namespace concept = concepts; 13 | # endif 14 | } // namespace boost::concept 15 | 16 | #endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP 17 | -------------------------------------------------------------------------------- /include/boost/concept/detail/borland.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP 5 | # define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP 6 | 7 | # include 8 | # include 9 | 10 | namespace boost { namespace concepts { 11 | 12 | template 13 | struct require; 14 | 15 | template 16 | struct require 17 | { 18 | enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; 19 | }; 20 | 21 | # define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ 22 | enum \ 23 | { \ 24 | BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 25 | boost::concepts::require::instantiate \ 26 | } 27 | 28 | }} // namespace boost::concept 29 | 30 | #endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP 31 | -------------------------------------------------------------------------------- /include/boost/concept/detail/concept_def.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP 5 | # define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP 6 | # include 7 | # include 8 | # include 9 | # include 10 | #endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP 11 | 12 | // BOOST_concept(SomeName, (p1)(p2)...(pN)) 13 | // 14 | // Expands to "template struct SomeName" 15 | // 16 | // Also defines an equivalent SomeNameConcept for backward compatibility. 17 | // Maybe in the next release we can kill off the "Concept" suffix for good. 18 | # define BOOST_concept(name, params) \ 19 | template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ 20 | struct name; /* forward declaration */ \ 21 | \ 22 | template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ 23 | struct BOOST_PP_CAT(name,Concept) \ 24 | : name< BOOST_PP_SEQ_ENUM(params) > \ 25 | { \ 26 | }; \ 27 | \ 28 | template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ 29 | struct name 30 | 31 | // Helper for BOOST_concept, above. 32 | # define BOOST_CONCEPT_typename(r, ignored, index, t) \ 33 | BOOST_PP_COMMA_IF(index) typename t 34 | 35 | -------------------------------------------------------------------------------- /include/boost/concept/detail/concept_undef.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | # undef BOOST_concept_typename 5 | # undef BOOST_concept 6 | -------------------------------------------------------------------------------- /include/boost/concept/detail/general.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP 5 | # define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 12 | # include 13 | # include 14 | # endif 15 | 16 | // This implementation works on Comeau and GCC, all the way back to 17 | // 2.95 18 | namespace boost { namespace concepts { 19 | 20 | template 21 | struct requirement_; 22 | 23 | namespace detail 24 | { 25 | template struct instantiate {}; 26 | } 27 | 28 | template 29 | struct requirement 30 | { 31 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 32 | # pragma GCC diagnostic push 33 | # pragma GCC diagnostic ignored "-Wnonnull" 34 | # endif 35 | static void failed() { ((Model*)0)->~Model(); } 36 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 37 | # pragma GCC diagnostic pop 38 | # endif 39 | }; 40 | 41 | struct failed {}; 42 | 43 | template 44 | struct requirement 45 | { 46 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 47 | # pragma GCC diagnostic push 48 | # pragma GCC diagnostic ignored "-Wnonnull" 49 | # endif 50 | static void failed() { ((Model*)0)->~Model(); } 51 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 52 | # pragma GCC diagnostic pop 53 | # endif 54 | }; 55 | 56 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 57 | 58 | template 59 | struct constraint 60 | { 61 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 62 | # pragma GCC diagnostic push 63 | # pragma GCC diagnostic ignored "-Wnonnull" 64 | # endif 65 | static void failed() { ((Model*)0)->constraints(); } 66 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 67 | # pragma GCC diagnostic pop 68 | # endif 69 | }; 70 | 71 | template 72 | struct requirement_ 73 | : boost::conditional< 74 | concepts::not_satisfied::value 75 | , constraint 76 | , requirement 77 | >::type 78 | {}; 79 | 80 | # else 81 | 82 | // For GCC-2.x, these can't have exactly the same name 83 | template 84 | struct requirement_ 85 | : requirement 86 | {}; 87 | 88 | # endif 89 | 90 | # define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ 91 | typedef ::boost::concepts::detail::instantiate< \ 92 | &::boost::concepts::requirement_::failed> \ 93 | BOOST_PP_CAT(boost_concept_check,__LINE__) \ 94 | BOOST_ATTRIBUTE_UNUSED 95 | 96 | }} 97 | 98 | #endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP 99 | -------------------------------------------------------------------------------- /include/boost/concept/detail/has_constraints.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP 5 | # define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | namespace boost { namespace concepts { 12 | 13 | namespace detail 14 | { 15 | 16 | // Here we implement the metafunction that detects whether a 17 | // constraints metafunction exists 18 | typedef char yes; 19 | typedef char (&no)[2]; 20 | 21 | template 22 | struct wrap_constraints {}; 23 | 24 | #if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__) 25 | // Work around the following bogus error in Sun Studio 11, by 26 | // turning off the has_constraints function entirely: 27 | // Error: complex expression not allowed in dependent template 28 | // argument expression 29 | inline no has_constraints_(...); 30 | #else 31 | template 32 | inline yes has_constraints_(Model*, wrap_constraints* = 0); 33 | inline no has_constraints_(...); 34 | #endif 35 | } 36 | 37 | // This would be called "detail::has_constraints," but it has a strong 38 | // tendency to show up in error messages. 39 | template 40 | struct not_satisfied 41 | { 42 | BOOST_STATIC_CONSTANT( 43 | bool 44 | , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) ); 45 | typedef boost::integral_constant type; 46 | }; 47 | 48 | }} // namespace boost::concepts::detail 49 | 50 | #endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP 51 | -------------------------------------------------------------------------------- /include/boost/concept/detail/msvc.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 5 | # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 12 | # include 13 | # include 14 | # endif 15 | 16 | # ifdef BOOST_MSVC 17 | # pragma warning(push) 18 | # pragma warning(disable:4100) 19 | # endif 20 | 21 | namespace boost { namespace concepts { 22 | 23 | 24 | template 25 | struct check 26 | { 27 | virtual void failed(Model* x) 28 | { 29 | x->~Model(); 30 | } 31 | }; 32 | 33 | # ifndef BOOST_NO_PARTIAL_SPECIALIZATION 34 | struct failed {}; 35 | template 36 | struct check 37 | { 38 | virtual void failed(Model* x) 39 | { 40 | x->~Model(); 41 | } 42 | }; 43 | # endif 44 | 45 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 46 | 47 | namespace detail 48 | { 49 | // No need for a virtual function here, since evaluating 50 | // not_satisfied below will have already instantiated the 51 | // constraints() member. 52 | struct constraint {}; 53 | } 54 | 55 | template 56 | struct require 57 | : boost::conditional< 58 | not_satisfied::value 59 | , detail::constraint 60 | # ifndef BOOST_NO_PARTIAL_SPECIALIZATION 61 | , check 62 | # else 63 | , check 64 | # endif 65 | >::type 66 | {}; 67 | 68 | # else 69 | 70 | template 71 | struct require 72 | # ifndef BOOST_NO_PARTIAL_SPECIALIZATION 73 | : check 74 | # else 75 | : check 76 | # endif 77 | {}; 78 | 79 | # endif 80 | 81 | # if BOOST_WORKAROUND(BOOST_MSVC, == 1310) 82 | 83 | // 84 | // The iterator library sees some really strange errors unless we 85 | // do things this way. 86 | // 87 | template 88 | struct require 89 | { 90 | virtual void failed(Model*) 91 | { 92 | require(); 93 | } 94 | }; 95 | 96 | # define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ 97 | enum \ 98 | { \ 99 | BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 100 | sizeof(::boost::concepts::require) \ 101 | } 102 | 103 | # else // Not vc-7.1 104 | 105 | template 106 | require 107 | require_(void(*)(Model)); 108 | 109 | # define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ 110 | enum \ 111 | { \ 112 | BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 113 | sizeof(::boost::concepts::require_((ModelFnPtr)0)) \ 114 | } 115 | 116 | # endif 117 | }} 118 | 119 | # ifdef BOOST_MSVC 120 | # pragma warning(pop) 121 | # endif 122 | 123 | #endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 124 | -------------------------------------------------------------------------------- /include/boost/concept/requires.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP 5 | # define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | namespace boost { 12 | 13 | // unaryfunptr_arg_type from parameter/aux_/parenthesized_type.hpp 14 | 15 | namespace ccheck_aux { 16 | 17 | // A metafunction that transforms void(*)(T) -> T 18 | template 19 | struct unaryfunptr_arg_type; 20 | 21 | template 22 | struct unaryfunptr_arg_type 23 | { 24 | typedef Arg type; 25 | }; 26 | 27 | template <> 28 | struct unaryfunptr_arg_type 29 | { 30 | typedef void type; 31 | }; 32 | 33 | } // namespace ccheck_aux 34 | 35 | // Template for use in handwritten assertions 36 | template 37 | struct requires_ : More 38 | { 39 | BOOST_CONCEPT_ASSERT((Model)); 40 | }; 41 | 42 | // Template for use by macros, where models must be wrapped in parens. 43 | // This isn't in namespace detail to keep extra cruft out of resulting 44 | // error messages. 45 | template 46 | struct _requires_ 47 | { 48 | enum { value = 0 }; 49 | BOOST_CONCEPT_ASSERT_FN(ModelFn); 50 | }; 51 | 52 | template 53 | struct Requires_ : ::boost::ccheck_aux::unaryfunptr_arg_type 54 | { 55 | }; 56 | 57 | # if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010)) 58 | # define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_::value) 59 | # else 60 | # define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_::value) 61 | # endif 62 | 63 | #if defined(NDEBUG) 64 | 65 | # define BOOST_CONCEPT_REQUIRES(models, result) \ 66 | typename ::boost::ccheck_aux::unaryfunptr_arg_type::type 67 | 68 | #elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 69 | 70 | // Same thing as below without the initial typename 71 | # define BOOST_CONCEPT_REQUIRES(models, result) \ 72 | ::boost::Requires_< \ 73 | (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ 74 | ::boost::ccheck_aux::unaryfunptr_arg_type \ 75 | >::type 76 | 77 | #else 78 | 79 | // This just ICEs on MSVC6 :( 80 | # define BOOST_CONCEPT_REQUIRES(models, result) \ 81 | typename ::boost::Requires_< \ 82 | (0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \ 83 | void(*)result \ 84 | >::type 85 | 86 | #endif 87 | 88 | // C++0x proposed syntax changed. This supports an older usage 89 | #define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result) 90 | 91 | } // namespace boost::concept_check 92 | 93 | #endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP 94 | -------------------------------------------------------------------------------- /include/boost/concept/usage.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP 5 | # define BOOST_CONCEPT_USAGE_DWA2006919_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | namespace boost { namespace concepts { 12 | 13 | template 14 | struct usage_requirements 15 | { 16 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 17 | # pragma GCC diagnostic push 18 | # pragma GCC diagnostic ignored "-Wnonnull" 19 | # endif 20 | ~usage_requirements() { ((Model*)0)->~Model(); } 21 | # if defined(BOOST_GCC) && (BOOST_GCC >= 110000) 22 | # pragma GCC diagnostic pop 23 | # endif 24 | }; 25 | 26 | # if BOOST_WORKAROUND(__GNUC__, <= 3) 27 | 28 | # define BOOST_CONCEPT_USAGE(model) \ 29 | model(); /* at least 2.96 and 3.4.3 both need this :( */ \ 30 | BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ 31 | ~model() 32 | 33 | # else 34 | 35 | # define BOOST_CONCEPT_USAGE(model) \ 36 | BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ 37 | ~model() 38 | 39 | # endif 40 | 41 | }} // namespace boost::concepts 42 | 43 | #endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP 44 | -------------------------------------------------------------------------------- /include/boost/concept_check/borland.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP 5 | # define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP 6 | 7 | namespace boost { 8 | 9 | template 10 | struct concept_check; 11 | 12 | template 13 | struct concept_check 14 | { 15 | enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; 16 | }; 17 | 18 | # define BOOST_CONCEPT_ASSERT( ModelInParens ) \ 19 | enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 20 | boost::concept_check::instantiate \ 21 | } 22 | 23 | } // namespace boost::concept_checking 24 | 25 | #endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP 26 | -------------------------------------------------------------------------------- /include/boost/concept_check/general.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 5 | # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 6 | 7 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 8 | # include 9 | # include 10 | # endif 11 | 12 | 13 | // This implementation works on GCC and Comeau, but has actually been 14 | // fairly carefully tuned to work on GCC versions starting with 15 | // gcc-2.95.x. If you're trying to get an additional compiler to pass 16 | // the tests you might consider breaking out a separate gcc.hpp and 17 | // starting over on the general case. 18 | namespace boost 19 | { 20 | namespace concept_checking 21 | { 22 | template struct instantiate {}; 23 | } 24 | 25 | template struct concept_check_; 26 | 27 | template 28 | void concept_check_failed() 29 | { 30 | ((Model*)0)->~Model(); 31 | } 32 | 33 | template 34 | struct concept_check 35 | { 36 | concept_checking::instantiate > x; 37 | enum { instantiate = 1 }; 38 | }; 39 | 40 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 41 | 42 | template 43 | void constraint_check_failed() 44 | { 45 | ((Model*)0)->constraints(); 46 | } 47 | 48 | template 49 | struct constraint_check 50 | { 51 | concept_checking::instantiate > x; 52 | enum { instantiate = 1 }; 53 | }; 54 | 55 | template 56 | struct concept_check_ 57 | : conditional< 58 | concept_checking::has_constraints::value 59 | , constraint_check 60 | , concept_check 61 | >::type 62 | {}; 63 | 64 | # else 65 | 66 | template 67 | struct concept_check_ 68 | : concept_check 69 | {}; 70 | 71 | # endif 72 | 73 | // Usage, in class or function context: 74 | // 75 | // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); 76 | # define BOOST_CONCEPT_ASSERT( ModelInParens ) \ 77 | enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 78 | ::boost::concept_check_::instantiate \ 79 | } 80 | } 81 | 82 | #endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 83 | -------------------------------------------------------------------------------- /include/boost/concept_check/has_constraints.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP 5 | # define BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP 6 | 7 | namespace boost { namespace concept_checking { 8 | 9 | // Here we implement the "metafunction" that detects whether a 10 | // constraints metafunction exists 11 | typedef char yes; 12 | typedef char (&no)[2]; 13 | 14 | template 15 | struct wrap_constraints {}; 16 | 17 | template 18 | inline yes has_constraints_(Model*, wrap_constraints* = 0); 19 | inline no has_constraints_(...); 20 | 21 | template 22 | struct has_constraints 23 | { 24 | BOOST_STATIC_CONSTANT( 25 | bool 26 | , value = sizeof( concept_checking::has_constraints_((Model*)0) ) == 1 ); 27 | }; 28 | 29 | }} // namespace boost::concept_checking 30 | 31 | #endif // BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP 32 | -------------------------------------------------------------------------------- /include/boost/concept_check/msvc.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 5 | # define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 6 | 7 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 8 | # include 9 | # include 10 | # endif 11 | 12 | 13 | namespace boost 14 | { 15 | namespace concept_checking 16 | { 17 | template 18 | struct concept_check_ 19 | { 20 | virtual void failed(Model* x) 21 | { 22 | x->~Model(); 23 | } 24 | }; 25 | } 26 | 27 | # ifdef BOOST_OLD_CONCEPT_SUPPORT 28 | 29 | namespace concept_checking 30 | { 31 | template 32 | struct constraint_check 33 | { 34 | virtual void failed(Model* x) 35 | { 36 | x->constraints(); 37 | } 38 | }; 39 | } 40 | 41 | template 42 | struct concept_check 43 | : conditional< 44 | concept_checking::has_constraints::value 45 | , concept_checking::constraint_check 46 | , concept_checking::concept_check_ 47 | >::type 48 | {}; 49 | 50 | # else 51 | 52 | template 53 | struct concept_check 54 | : concept_checking::concept_check_ 55 | {}; 56 | 57 | # endif 58 | 59 | # if BOOST_WORKAROUND(BOOST_MSVC, == 1310) 60 | 61 | // 62 | // The iterator library sees some really strange errors unless we 63 | // use partial specialization to extract the model type with 64 | // msvc-7.1 65 | // 66 | template 67 | struct concept_check 68 | : concept_check 69 | { }; 70 | 71 | # define BOOST_CONCEPT_ASSERT( ModelInParens ) \ 72 | enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 73 | sizeof(::boost::concept_check) \ 74 | } 75 | 76 | # else 77 | 78 | template 79 | concept_check 80 | concept_check_(void(*)(Model)); 81 | 82 | # define BOOST_CONCEPT_ASSERT( ModelInParens ) \ 83 | enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \ 84 | sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \ 85 | } 86 | 87 | # endif 88 | } 89 | 90 | #endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP 91 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/concept_check/0ef7f2b5daeaa125a53d98affba8f40091d24b17/index.html -------------------------------------------------------------------------------- /meta/explicit-failures-markup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | This version of the Rogue Wave library fails to provide all 24 | needed addition operators for the iterator type and the 25 | difference type of std::deque. 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "concept_check", 3 | "name": "Concept Check", 4 | "authors": [ 5 | "Jeremy Siek" 6 | ], 7 | "description": "Tools for generic programming.", 8 | "category": [ 9 | "Correctness", 10 | "Generic" 11 | ], 12 | "maintainers": [ 13 | "Jeremy Siek " 14 | ], 15 | "cxxstd": "03" 16 | } 17 | -------------------------------------------------------------------------------- /prog_with_concepts.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | Programming With Concepts 15 | 16 | 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Programming with Concepts

26 | 27 |

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

32 | 33 |

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

35 | 36 |

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

42 | 43 |

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

47 | 48 |

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

107 | 108 |

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

127 | 128 |

Next: Implementation
129 | Prev: Concept Covering and 130 | Archetypes

131 |
132 | 133 | 134 | 135 | 136 | 137 | 142 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 139 | Lumsdaine(lums@osl.iu.edu), 140 | 2007 David Abrahams. 141 |
143 | 144 | 145 | -------------------------------------------------------------------------------- /reference.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | Boost Concept Checking Reference 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Reference

25 | 26 |
    27 |
  1. Macros
  2. 28 | 29 |
  3. Basic Concept Checking Classes
  4. 30 | 31 |
  5. Iterator Concept Checking 32 | Classes
  6. 33 | 34 |
  7. Function Object Concept Checking 35 | Classes
  8. 36 | 37 |
  9. Container Concept Checking 38 | Classes
  10. 39 | 40 |
  11. Basic Archetype Classes
  12. 41 | 42 |
  13. Iterator Archetype Classes
  14. 43 | 44 |
  15. Function Object Archetype 45 | Classes
  16. 46 | 47 |
  17. Container Archetype Classes
  18. 48 | 49 |
  19. Deprecated Functions
  20. 50 | 51 |
  21. Deprecated Macros
  22. 52 | 53 |
  23. Deprecated Concept 54 | Checking Classes
  24. 55 |
56 | 57 |

Macros

58 |
 59 | #include "boost/concept/assert.hpp"
 60 | 
 61 | BOOST_CONCEPT_ASSERT((concept checking class template specialization));
 62 | 
63 | 64 |

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

68 | 69 |
 70 | #include "boost/concept/requires.hpp"
 71 | 
 72 | template <…template parameters…>
 73 | BOOST_CONCEPT_REQUIRES(
 74 |   ((concept checking class template specialization1)) 
 75 |   ((concept checking class template specialization2))… 
 76 |   ((concept checking class template specializationn)),
 77 |   (function return type)
 78 | ) function_template_name(…function parameters…)
 79 | 
80 | 81 |

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

85 | 86 |

Basic Concept Checking 87 | Classes

88 |
 89 | #include "boost/concept_check.hpp"
 90 | 
 91 | template <class T>
 92 | struct Integer; // Is T a built-in integer type?
 93 | 
 94 | template <class T>
 95 | struct SignedInteger; // Is T a built-in signed integer type?
 96 | 
 97 | template <class T>
 98 | struct UnsignedInteger; // Is T a built-in unsigned integer type?
 99 | 
100 | template <class X, class Y>
101 | struct Convertible; // Is X convertible to Y?
102 | 
103 | template <class T>
104 | struct Assignable; // Standard ref 23.1
106 | 
107 | template <class T>
108 | struct SGIAssignable;
110 | 
111 | template <class T>
112 | struct DefaultConstructible;
114 | 
115 | template <class T> 
116 | struct CopyConstructible; // Standard ref 20.1.3
118 | 
119 | template <class T> 
120 | struct EqualityComparable; // Standard ref 20.1.1
122 | 
123 | template <class T>
124 | struct LessThanComparable; // Standard ref 20.1.2
126 | 
127 | template <class T>
128 | struct Comparable; // The SGI STL LessThanComparable concept
130 | 
131 | 132 |

Iterator Concept 133 | Checking Classes

134 |
135 | template <class Iter>
136 | struct InputIterator; // Standard ref 24.1.1 Table 72
138 | 
139 | template <class Iter, class T> 
140 | struct OutputIterator; // Standard ref 24.1.2 Table 73
142 | 
143 | template <class Iter> 
144 | struct ForwardIterator; // Standard ref 24.1.3 Table 74
146 | 
147 | template <class Iter> 
148 | struct Mutable_ForwardIterator;
149 | 
150 | template <class Iter> 
151 | struct BidirectionalIterator; // Standard ref 24.1.4 Table 75
153 | 
154 | template <class Iter> 
155 | struct Mutable_BidirectionalIterator;
156 | 
157 | template <class Iter> 
158 | struct RandomAccessIterator; // Standard ref 24.1.5 Table 76
160 | 
161 | template <class Iter> 
162 | struct Mutable_RandomAccessIterator;
163 | 
164 | 165 |

Function Object Concept Checking 167 | Classes

168 |
169 | #include "boost/concept_check.hpp"
170 | 
171 | template <class Func, class Return>
172 | struct Generator;
173 | 
174 | template <class Func, class Return, class Arg>
175 | struct UnaryFunction;
177 | 
178 | template <class Func, class Return, class First, class Second>
179 | struct BinaryFunction;
181 | 
182 | template <class Func, class Arg>
183 | struct UnaryPredicate;
185 | 
186 | template <class Func, class First, class Second>
187 | struct BinaryPredicate;
189 | 
190 | template <class Func, class First, class Second>
191 | struct Const_BinaryPredicate;
192 | 
193 | template <class Func, class Return>
194 | struct AdaptableGenerator;
196 | 
197 | template <class Func, class Return, class Arg>
198 | struct AdaptableUnaryFunction;
200 | 
201 | template <class Func, class First, class Second>
202 | struct AdaptableBinaryFunction;
204 | 
205 | template <class Func, class Arg>
206 | struct AdaptablePredicate;
208 | 
209 | template <class Func, class First, class Second>
210 | struct AdaptableBinaryPredicate;
212 | 
213 | 214 |

Container Concept 215 | Checking Classes

216 |
217 | #include "boost/concept_check.hpp"
218 | 
219 | template <class C>
220 | struct Container; // Standard ref 23.1 Table 65
222 | 
223 | template <class C>
224 | struct Mutable_Container;
225 | 
226 | template <class C>
227 | struct ForwardContainer;
229 | 
230 | template <class C>
231 | struct Mutable_ForwardContainer;
232 | 
233 | template <class C>
234 | struct ReversibleContainer; // Standard ref 23.1 Table 66
236 | 
237 | template <class C>
238 | struct Mutable_ReversibleContainer;
239 | 
240 | template <class C>
241 | struct RandomAccessContainer;
243 | 
244 | template <class C>
245 | struct Mutable_RandomAccessContainer;
246 | 
247 | template <class C>
248 | struct Sequence; // Standard ref 23.1.1
250 | 
251 | template <class C>
252 | struct FrontInsertionSequence;
254 | 
255 | template <class C>
256 | struct BackInsertionSequence;
258 | 
259 | template <class C>
260 | struct AssociativeContainer; // Standard ref 23.1.2 Table 69
262 | 
263 | template <class C>
264 | struct UniqueAssociativeContainer;
266 | 
267 | template <class C>
268 | struct MultipleAssociativeContainer;
270 | 
271 | template <class C>
272 | struct SimpleAssociativeContainer;
274 | 
275 | template <class C>
276 | struct PairAssociativeContainer;
278 | 
279 | template <class C>
280 | struct SortedAssociativeContainer;
282 | 
283 | template <class C>
284 | struct Collection;
286 | 
287 | 288 |

Basic Archetype 289 | Classes

290 |
291 | #include "boost/concept_archetype.hpp"
292 | 
293 | template <class T = int>
294 | class null_archetype; // A type that models no concepts.
295 | 
296 | template <class Base = null_archetype>
297 | class default_constructible_archetype;
298 | 
299 | template <class Base = null_archetype>
300 | class assignable_archetype;
301 | 
302 | template <class Base = null_archetype>
303 | class copy_constructible_archetype;
304 | 
305 | template <class Base = null_archetype>
306 | class equality_comparable_archetype;
307 | 
308 | template <class T, class Base = null_archetype>
309 | class convertible_to_archetype;
310 | 
311 | 312 |

Iterator Archetype 313 | Classes

314 |
315 | #include "boost/concept_archetype.hpp"
316 | 
317 | template <class ValueType>
318 | class trivial_iterator_archetype;
319 | 
320 | template <class ValueType>
321 | class mutable_trivial_iterator_archetype;
322 | 
323 | template <class ValueType>
324 | class input_iterator_archetype;
325 | 
326 | template <class ValueType>
327 | class forward_iterator_archetype;
328 | 
329 | template <class ValueType>
330 | class bidirectional_iterator_archetype;
331 | 
332 | template <class ValueType>
333 | class random_access_iterator_archetype;
334 | 
335 | 336 |

Function Object Archetype Classes

338 |
339 | #include "boost/concept_archetype.hpp"
340 | 
341 | template <class Arg, class Return>
342 | class unary_function_archetype;
343 | 
344 | template <class Arg1, class Arg2, class Return>
345 | class binary_function_archetype;
346 | 
347 | template <class Arg>
348 | class predicate_archetype;
349 | 
350 | template <class Arg1, class Arg2>
351 | class binary_predicate_archetype;
352 | 
353 | 354 |

Container 355 | Archetype Classes

356 |
357 | UNDER CONSTRUCTION
358 | 
359 | 360 |

Deprecated 361 | Functions

362 |
363 | #include "boost/concept_check.hpp"
364 | 
365 | template <class Concept>
366 | void function_requires();
367 | 
368 | 369 |

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

Deprecated 376 | Macros

377 |
378 | #include "boost/concept_check.hpp"
379 | 
380 | // Apply concept checks in class definitions.
381 | BOOST_CLASS_REQUIRE(type, namespace-of-concept, concept);
382 | BOOST_CLASS_REQUIRE2(type1, type2, namespace-of-concept, concept);
383 | BOOST_CLASS_REQUIRE3(type1, type2, type3, namespace-of-concept, concept);
384 | BOOST_CLASS_REQUIRE4(type1, type2, type3, type4, namespace-of-concept, concept);
385 | 
386 | // Apply concept checks in class definitions.
387 | BOOST_CLASS_REQUIRES(type, concept);
388 | BOOST_CLASS_REQUIRES2(type1, type2, concept);
389 | BOOST_CLASS_REQUIRES3(type1, type2, type3, concept);
390 | BOOST_CLASS_REQUIRES4(type1, type2, type3, type4, concept);
391 | 
392 | 393 |

Deprecated Concept Checking 395 | Classes

396 | 397 |

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

402 | 403 |

Back to Introduction
404 | Prev: Implementation

405 |
406 | 407 | 408 | 409 | 410 | 411 | 415 | 416 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 413 | Lumsdaine(lums@osl.iu.edu), 2007 414 | David Abrahams.
417 | 418 | 419 | -------------------------------------------------------------------------------- /test/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # Copyright David Abrahams, Jeremy Siek, Vladimir Prus 2 | # 2006. Distributed under the Boost Software License, Version 3 | # 1.0. (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | import testing ; 6 | 7 | project : requirements 8 | /boost/core//boost_core 9 | /boost/concept_check//boost_concept_check 10 | ; 11 | 12 | test-suite concept_check 13 | : [ link stl_concept_covering.cpp ] 14 | [ run stl_concept_check.cpp ] 15 | [ run concept_check_test.cpp ] 16 | [ run class_concept_check_test.cpp ] 17 | [ compile-fail concept_check_fail_expected.cpp ] 18 | [ compile-fail class_concept_fail_expected.cpp ] 19 | 20 | [ run where.cpp ] 21 | [ compile-fail where_fail.cpp ] 22 | [ compile-fail usage_fail.cpp ] 23 | 24 | # Backward compatibility tests 25 | [ run old_concept_pass.cpp ] 26 | [ compile-fail function_requires_fail.cpp ] 27 | [ compile-fail old_concept_function_fail.cpp ] 28 | [ compile-fail old_concept_class_fail.cpp ] 29 | ; 30 | 31 | -------------------------------------------------------------------------------- /test/class_concept_check_test.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2000. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #include 7 | 8 | /* 9 | 10 | This file verifies that the BOOST_CLASS_REQUIRE macro of the Boost 11 | Concept Checking Library does not cause errors when it is not suppose 12 | to. 13 | 14 | */ 15 | 16 | struct foo { bool operator()(int) { return true; } }; 17 | struct bar { bool operator()(int, char) { return true; } }; 18 | 19 | class class_requires_test 20 | { 21 | BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); 22 | typedef int* int_ptr; typedef const int* const_int_ptr; 23 | BOOST_CONCEPT_ASSERT((boost::EqualOp)); 24 | BOOST_CONCEPT_ASSERT((boost::UnaryFunction)); 25 | BOOST_CONCEPT_ASSERT((boost::BinaryFunction)); 26 | }; 27 | 28 | int 29 | main() 30 | { 31 | class_requires_test x; 32 | boost::ignore_unused_variable_warning(x); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test/class_concept_fail_expected.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek, David Abrahams 2000-2006. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | // 6 | // Change Log: 7 | // 20 Jan 2001 - Added warning suppression (David Abrahams) 8 | 9 | #include 10 | 11 | /* 12 | 13 | This file verifies that class_requires of the Boost Concept Checking 14 | Library catches errors when it is supposed to. 15 | 16 | */ 17 | 18 | struct foo { }; 19 | 20 | template 21 | class class_requires_test 22 | { 23 | BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); 24 | }; 25 | 26 | int 27 | main() 28 | { 29 | class_requires_test x; 30 | (void)x; // suppress unused variable warning 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test/cmake_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2021-2024 Alexander Grund 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 | 5 | cmake_minimum_required(VERSION 3.5...3.16) 6 | 7 | project(cmake_subdir_test LANGUAGES CXX) 8 | 9 | # Those 2 should work the same 10 | # while using find_package for the installed Boost avoids the need to manually specify dependencies 11 | if(BOOST_CI_INSTALL_TEST) 12 | find_package(boost_concept_check REQUIRED) 13 | else() 14 | set(BOOST_INCLUDE_LIBRARIES concept_check) 15 | add_subdirectory(../../../.. deps/boost EXCLUDE_FROM_ALL) 16 | endif() 17 | 18 | add_executable(main main.cpp) 19 | target_link_libraries(main Boost::concept_check) 20 | 21 | enable_testing() 22 | add_test(NAME main COMMAND main) 23 | -------------------------------------------------------------------------------- /test/cmake_test/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 5 | # define BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | namespace fake 12 | { 13 | using namespace boost; 14 | 15 | template 16 | BOOST_CONCEPT_REQUIRES( 17 | ((Mutable_RandomAccessIterator)) 18 | ((LessThanComparable::value_type>)) 19 | 20 | , (void)) 21 | sort(RanIter,RanIter) 22 | { 23 | 24 | } 25 | } 26 | 27 | #endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 28 | // Copyright David Abrahams 2006. Distributed under the Boost 29 | // Software License, Version 1.0. (See accompanying 30 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 31 | #include 32 | #undef NDEBUG 33 | 34 | int main() 35 | { 36 | std::vector v; 37 | fake::sort(v.begin(), v.end()); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test/concept_check_fail_expected.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek, David Abrahams 2000-2006. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifdef NDEBUG 7 | # undef NDEBUG 8 | #endif 9 | 10 | #include 11 | 12 | /* 13 | 14 | This file verifies that BOOST_CONCEPT_ASSERT catches errors in 15 | function context. 16 | 17 | */ 18 | 19 | struct foo { }; 20 | 21 | int 22 | main() 23 | { 24 | BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/concept_check_test.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2000. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #include 7 | #include 8 | 9 | /* 10 | 11 | This file verifies that function_requires() of the Boost Concept 12 | Checking Library does not cause errors when it is not suppose to 13 | and verifies that the concept archetypes meet the requirements of 14 | their matching concepts. 15 | 16 | */ 17 | 18 | 19 | int 20 | main() 21 | { 22 | using namespace boost; 23 | 24 | //=========================================================================== 25 | // Basic Concepts 26 | { 27 | typedef default_constructible_archetype<> foo; 28 | function_requires< DefaultConstructible >(); 29 | } 30 | { 31 | typedef assignable_archetype<> foo; 32 | function_requires< Assignable >(); 33 | } 34 | { 35 | typedef copy_constructible_archetype<> foo; 36 | function_requires< CopyConstructible >(); 37 | } 38 | { 39 | typedef sgi_assignable_archetype<> foo; 40 | function_requires< SGIAssignable >(); 41 | } 42 | { 43 | typedef copy_constructible_archetype<> foo; 44 | typedef convertible_to_archetype convertible_to_foo; 45 | function_requires< Convertible >(); 46 | } 47 | { 48 | function_requires< Convertible >(); 49 | } 50 | { 51 | typedef equality_comparable_archetype<> foo; 52 | function_requires< EqualityComparable >(); 53 | } 54 | { 55 | typedef less_than_comparable_archetype<> foo; 56 | function_requires< LessThanComparable >(); 57 | } 58 | { 59 | typedef comparable_archetype<> foo; 60 | function_requires< Comparable >(); 61 | } 62 | { 63 | typedef equal_op_first_archetype<> First; 64 | typedef equal_op_second_archetype<> Second; 65 | function_requires< EqualOp >(); 66 | } 67 | { 68 | typedef not_equal_op_first_archetype<> First; 69 | typedef not_equal_op_second_archetype<> Second; 70 | function_requires< NotEqualOp >(); 71 | } 72 | { 73 | typedef less_than_op_first_archetype<> First; 74 | typedef less_than_op_second_archetype<> Second; 75 | function_requires< LessThanOp >(); 76 | } 77 | { 78 | typedef less_equal_op_first_archetype<> First; 79 | typedef less_equal_op_second_archetype<> Second; 80 | function_requires< LessEqualOp >(); 81 | } 82 | { 83 | typedef greater_than_op_first_archetype<> First; 84 | typedef greater_than_op_second_archetype<> Second; 85 | function_requires< GreaterThanOp >(); 86 | } 87 | { 88 | typedef greater_equal_op_first_archetype<> First; 89 | typedef greater_equal_op_second_archetype<> Second; 90 | function_requires< GreaterEqualOp >(); 91 | } 92 | 93 | { 94 | typedef copy_constructible_archetype<> Return; 95 | typedef plus_op_first_archetype First; 96 | typedef plus_op_second_archetype Second; 97 | function_requires< PlusOp >(); 98 | } 99 | 100 | //=========================================================================== 101 | // Function Object Concepts 102 | 103 | { 104 | typedef generator_archetype > foo; 105 | function_requires< Generator > >(); 106 | } 107 | #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 108 | { 109 | function_requires< Generator< void_generator_archetype, void > >(); 110 | } 111 | #endif 112 | { 113 | typedef unary_function_archetype F; 114 | function_requires< UnaryFunction >(); 115 | } 116 | { 117 | typedef binary_function_archetype F; 118 | function_requires< BinaryFunction >(); 119 | } 120 | { 121 | typedef unary_predicate_archetype F; 122 | function_requires< UnaryPredicate >(); 123 | } 124 | { 125 | typedef binary_predicate_archetype F; 126 | function_requires< BinaryPredicate >(); 127 | } 128 | 129 | //=========================================================================== 130 | // Iterator Concepts 131 | { 132 | typedef input_iterator_archetype > Iter; 133 | function_requires< InputIterator >(); 134 | } 135 | { 136 | typedef output_iterator_archetype Iter; 137 | function_requires< OutputIterator >(); 138 | } 139 | { 140 | typedef input_output_iterator_archetype Iter; 141 | function_requires< InputIterator >(); 142 | function_requires< OutputIterator >(); 143 | } 144 | { 145 | typedef forward_iterator_archetype > Iter; 146 | function_requires< ForwardIterator >(); 147 | } 148 | { 149 | typedef mutable_forward_iterator_archetype > Iter; 150 | function_requires< Mutable_ForwardIterator >(); 151 | } 152 | { 153 | typedef bidirectional_iterator_archetype > Iter; 154 | function_requires< BidirectionalIterator >(); 155 | } 156 | { 157 | typedef mutable_bidirectional_iterator_archetype > 158 | Iter; 159 | function_requires< Mutable_BidirectionalIterator >(); 160 | } 161 | { 162 | typedef random_access_iterator_archetype > Iter; 163 | function_requires< RandomAccessIterator >(); 164 | } 165 | { 166 | typedef mutable_random_access_iterator_archetype > 167 | Iter; 168 | function_requires< Mutable_RandomAccessIterator >(); 169 | } 170 | 171 | //=========================================================================== 172 | // Container Concepts 173 | 174 | // UNDER CONSTRUCTION 175 | 176 | return 0; 177 | } 178 | -------------------------------------------------------------------------------- /test/fake_sort.hpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 5 | # define BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 6 | 7 | # include 8 | # include 9 | # include 10 | 11 | namespace fake 12 | { 13 | using namespace boost; 14 | 15 | template 16 | BOOST_CONCEPT_REQUIRES( 17 | ((Mutable_RandomAccessIterator)) 18 | ((LessThanComparable::value_type>)) 19 | 20 | , (void)) 21 | sort(RanIter,RanIter) 22 | { 23 | 24 | } 25 | } 26 | 27 | #endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP 28 | -------------------------------------------------------------------------------- /test/function_requires_fail.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2000. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifdef NDEBUG 7 | # undef NDEBUG 8 | #endif 9 | 10 | #include 11 | 12 | /* 13 | 14 | This file verifies that function_requires() of the Boost Concept 15 | Checking Library catches errors when it is suppose to. 16 | 17 | */ 18 | 19 | struct foo { }; 20 | 21 | int 22 | main() 23 | { 24 | boost::function_requires< boost::EqualityComparable >(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/old_concept_class_fail.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek, David Abrahams 2000-2006. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | // 6 | // Change Log: 7 | // 20 Jan 2001 - Added warning suppression (David Abrahams) 8 | 9 | #include "old_concepts.hpp" 10 | 11 | // This file verifies that concepts written the old way still catch 12 | // errors in class context. This is not expected to work on compilers 13 | // without SFINAE support. 14 | 15 | struct foo { }; 16 | 17 | class class_requires_test 18 | { 19 | BOOST_CLASS_REQUIRE(foo, old, EqualityComparableConcept); 20 | }; 21 | 22 | int 23 | main() 24 | { 25 | class_requires_test x; 26 | (void)x; // suppress unused variable warning 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test/old_concept_function_fail.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2000. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #ifdef NDEBUG 7 | # undef NDEBUG 8 | #endif 9 | 10 | #include "old_concepts.hpp" 11 | 12 | // This file verifies that concepts written the old way still catch 13 | // errors in function context. This is not expected to work on 14 | // compilers without SFINAE support. 15 | 16 | struct foo { }; 17 | 18 | int 19 | main() 20 | { 21 | boost::function_requires< old::EqualityComparableConcept >(); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/old_concept_pass.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek, David Abrahams 2000-2006. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | #include 7 | #include "old_concepts.hpp" 8 | 9 | // This test verifies that use of the old-style concept checking 10 | // classes still compiles (but not that it detects constraint 11 | // violations). We check them with the old-style macros just for 12 | // completeness, since those macros stranslate into 13 | // BOOST_CONCEPT_ASSERTs. 14 | 15 | struct foo { bool operator()(int) { return true; } }; 16 | struct bar { bool operator()(int, char) { return true; } }; 17 | 18 | 19 | class class_requires_test 20 | { 21 | BOOST_CLASS_REQUIRE(int, old, EqualityComparableConcept); 22 | typedef int* int_ptr; typedef const int* const_int_ptr; 23 | BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, old, EqualOpConcept); 24 | BOOST_CLASS_REQUIRE3(foo, bool, int, old, UnaryFunctionConcept); 25 | BOOST_CLASS_REQUIRE4(bar, bool, int, char, old, BinaryFunctionConcept); 26 | }; 27 | 28 | int 29 | main() 30 | { 31 | class_requires_test x; 32 | boost::ignore_unused_variable_warning(x); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test/old_concepts.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Jeremy Siek, David Abrahams 2000-2006. Distributed under 2 | // the Boost Software License, Version 1.0. (See accompanying file 3 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #ifndef BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP 5 | # define BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP 6 | 7 | #include 8 | 9 | namespace old 10 | { 11 | template 12 | void require_boolean_expr(const TT& t) { 13 | bool x = t; 14 | boost::ignore_unused_variable_warning(x); 15 | } 16 | 17 | template 18 | struct EqualityComparableConcept 19 | { 20 | void constraints() { 21 | boost::require_boolean_expr(a == b); 22 | boost::require_boolean_expr(a != b); 23 | } 24 | TT a, b; 25 | }; 26 | 27 | template 28 | struct UnaryFunctionConcept 29 | { 30 | // required in case any of our template args are const-qualified: 31 | UnaryFunctionConcept(); 32 | 33 | void constraints() { 34 | r = f(arg); // require operator() 35 | } 36 | Func f; 37 | Arg arg; 38 | Return r; 39 | }; 40 | 41 | template 42 | struct BinaryFunctionConcept 43 | { 44 | void constraints() { 45 | r = f(first, second); // require operator() 46 | } 47 | Func f; 48 | First first; 49 | Second second; 50 | Return r; 51 | }; 52 | 53 | #define DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ 54 | template \ 55 | struct NAME { \ 56 | void constraints() { (void)constraints_(); } \ 57 | bool constraints_() { \ 58 | return a OP b; \ 59 | } \ 60 | First a; \ 61 | Second b; \ 62 | } 63 | 64 | DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept); 65 | } 66 | 67 | #endif // BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP 68 | -------------------------------------------------------------------------------- /test/stl_concept_check.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2000. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | // 7 | // This file checks to see if various standard container 8 | // implementations live up to requirements specified in the C++ 9 | // standard. As many implementations do not live to the requirements, 10 | // it is not uncommon for this file to fail to compile. The 11 | // BOOST_HIDE_EXPECTED_ERRORS macro is provided here if you want to 12 | // see as much of this file compile as possible. 13 | // 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #if 0 24 | #include 25 | #endif 26 | 27 | // Define this macro if you want to hide the expected error, that is, 28 | // error in the various C++ standard library implementations. 29 | // 30 | //#define BOOST_HIDE_EXPECTED_ERRORS 31 | 32 | int 33 | main() 34 | { 35 | using namespace boost; 36 | 37 | #if defined(_ITERATOR_) && defined(BOOST_HIDE_EXPECTED_ERRORS) 38 | // VC++ STL implementation is not standard conformant and 39 | // fails to pass these concept checks 40 | #else 41 | typedef std::vector Vector; 42 | typedef std::deque Deque; 43 | typedef std::list List; 44 | 45 | // VC++ missing pointer and const_pointer typedefs 46 | function_requires< Mutable_RandomAccessContainer >(); 47 | function_requires< BackInsertionSequence >(); 48 | 49 | #if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS)) 50 | #if !((defined(__sgi) || (defined(__DECCXX) && defined(_RWSTD_VER) && _RWSTD_VER <= 0x0203)) \ 51 | && defined(BOOST_HIDE_EXPECTED_ERRORS)) 52 | // old deque iterator missing n + iter operation 53 | function_requires< Mutable_RandomAccessContainer >(); 54 | #endif 55 | // warnings about signed and unsigned in old deque version 56 | function_requires< FrontInsertionSequence >(); 57 | function_requires< BackInsertionSequence >(); 58 | #endif 59 | 60 | // VC++ missing pointer and const_pointer typedefs 61 | function_requires< Mutable_ReversibleContainer >(); 62 | function_requires< FrontInsertionSequence >(); 63 | function_requires< BackInsertionSequence >(); 64 | 65 | #if 0 66 | typedef BOOST_STD_EXTENSION_NAMESPACE::slist SList; 67 | function_requires< FrontInsertionSequence >(); 68 | #endif 69 | 70 | typedef std::set Set; 71 | typedef std::multiset MultiSet; 72 | typedef std::map Map; 73 | typedef std::multimap MultiMap; 74 | 75 | function_requires< SortedAssociativeContainer >(); 76 | function_requires< SimpleAssociativeContainer >(); 77 | function_requires< UniqueAssociativeContainer >(); 78 | 79 | function_requires< SortedAssociativeContainer >(); 80 | function_requires< SimpleAssociativeContainer >(); 81 | function_requires< MultipleAssociativeContainer >(); 82 | 83 | function_requires< SortedAssociativeContainer >(); 84 | function_requires< UniqueAssociativeContainer >(); 85 | function_requires< PairAssociativeContainer >(); 86 | 87 | function_requires< SortedAssociativeContainer >(); 88 | function_requires< MultipleAssociativeContainer >(); 89 | function_requires< PairAssociativeContainer >(); 90 | #endif 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /test/usage_fail.cpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | 5 | #include 6 | #include 7 | 8 | template 9 | struct StringInitializable 10 | { 11 | typedef int associated; 12 | BOOST_CONCEPT_USAGE(StringInitializable) 13 | { 14 | T x = "foo"; 15 | boost::ignore_unused(x); 16 | } 17 | }; 18 | 19 | // Test that accessing an associated type will actually exercise usage 20 | // requirements 21 | typedef StringInitializable::associated tee; 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/where.cpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #include 5 | #undef NDEBUG 6 | #include "fake_sort.hpp" 7 | 8 | int main() 9 | { 10 | std::vector v; 11 | fake::sort(v.begin(), v.end()); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/where_fail.cpp: -------------------------------------------------------------------------------- 1 | // Copyright David Abrahams 2006. Distributed under the Boost 2 | // Software License, Version 1.0. (See accompanying 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 4 | #include 5 | #undef NDEBUG 6 | #include "fake_sort.hpp" 7 | 8 | int main() 9 | { 10 | std::list v; 11 | fake::sort(v.begin(), v.end()); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /using_concept_check.htm: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | Using Concept Checks 16 | 17 | 18 | 19 | 21 | C++ Boost
23 | 24 |

Using Concept 25 | Checks

26 | 27 |

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

41 | 42 |

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

48 |
 49 | template <class T>
 50 | struct EqualityComparable;
 51 | 
52 | 53 |

The template argument is the type to be checked. That is, the purpose of 54 | EqualityComparable<T> is to make sure that 55 | T models the EqualityComparable concept.

56 | 57 |

BOOST_CONCEPT_ASSERT()

58 | 59 |

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

65 |
 66 | // In my library:
 67 | template <class T>
 68 | void generic_library_function(T x)
 69 | {
 70 |   BOOST_CONCEPT_ASSERT((EqualityComparable<T>));
 71 |   // ...
 72 | };
 73 | 
 74 | template <class It>
 75 | class generic_library_class
 76 | {
 77 |   BOOST_CONCEPT_ASSERT((RandomAccessIterator<It>));
 78 |   // ...
 79 | };
 80 | 
 81 | // In the user's code:  
 82 | class foo {
 83 |   //... 
 84 | };
 85 | 
 86 | int main() {
 87 |   foo x;
 88 |   generic_library_function(x);
 89 |   generic_library_class<std::vector<char>::iterator> y;
 90 |   //... 
 91 | }
 92 | 
93 | 94 |

BOOST_CONCEPT_REQUIRES

95 | 96 |

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

107 | 108 |

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

116 |
117 | template <class RanIter>
118 | BOOST_CONCEPT_REQUIRES(
119 |     ((Mutable_RandomAccessIterator<RanIter>))
120 |     ((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>)),
121 |     (void)) // return type
122 |     stable_sort(RanIter,RanIter);
123 | 
124 | 125 |

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

132 | 133 |

Multi-Type Concepts

134 | 135 |

Some concepts deal with more than one type. In this case the 136 | corresponding concept checking class will have multiple template 137 | parameters. The following example shows how BOOST_CONCEPT_REQUIRES 138 | is used with the ReadWritePropertyMap 140 | concept, which takes two type parameters: a property map and the key type 141 | for the map.

142 |
143 | template <class G, class Buffer, class BFSVisitor, 
144 |           class ColorMap>
145 | BOOST_CONCEPT_REQUIRES(
146 |   ((ReadWritePropertyMap<ColorMap, typename IncidenceGraph<G>::vertex_descriptor>)),
147 |   (void)) // return type
148 | breadth_first_search(G& g, 
149 |   typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
150 |   Buffer& Q, BFSVisitor vis, ColorMap color)
151 | {
152 |   typedef typename IncidenceGraph<G>::vertex_descriptor Vertex;
153 |   ...
154 | }
155 | 
156 | 157 |

Although concept checks are designed for use by generic library 158 | implementors, they can also be useful to end users. Sometimes one may not 159 | be sure whether some type models a particular concept. The syntactic 160 | requirements, at least, can easily be checked by creating a small program 161 | and using BOOST_CONCEPT_ASSERT with the type and concept in 162 | question. For example:

163 |
164 | // Make sure list<int> has bidirectional iterators.
166 | BOOST_CONCEPT_ASSERT((BidirectionalIterator<std::list<int>::iterator>));
167 | 
168 | 169 |

Prev: Concept Checking 170 | Introduction
171 | Next: Creating Concept Checking 172 | Classes

173 |
174 | 175 | 176 | 177 | 178 | 179 | 183 | 184 |
Copyright © 2000Jeremy Siek(jsiek@osl.iu.edu) Andrew 181 | Lumsdaine(lums@osl.iu.edu), 2007 182 | David Abrahams.
185 | 186 | 187 | --------------------------------------------------------------------------------