1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-13 17:48:00 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
# Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE.txt)
#
# Copyright Rene Rivera 2020.
# For Drone CI we use the Starlark scripting language to reduce duplication.
# As the yaml syntax for Drone CI is rather limited.
#
#
globalenv={'B2_VARIANT': 'variant=release,debug'}
linuxglobalimage="cppalliance/droneubuntu1604:1"
windowsglobalimage="cppalliance/dronevs2019"
def main(ctx):
return [
linux_cxx("B2_TOOLSET=gcc-4.8 B2_CXXSTD=03,11 Job 0", "g++-4.8", packages="g++-4.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-4.8', 'B2_CXXSTD': '03,11', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=gcc-5 B2_CXXSTD=11 Job 1", "g++-5", packages="g++-5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-5', 'B2_CXXSTD': '11', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=gcc-6 B2_CXXSTD=11,14 Job 2", "g++-6", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-6', 'B2_CXXSTD': '11,14', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=gcc-7 B2_CXXSTD=11,14,17 Job 3", "g++-7", packages="g++-7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-7', 'B2_CXXSTD': '11,14,17', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=gcc-8 B2_CXXSTD=14,17,2a Job 4", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'gcc-8', 'B2_CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-3.8 B2_CXXSTD=03,11,14 Job 5", "clang++-3.8", packages="clang-3.8 libstdc++-6-dev", llvm_os="xenial", llvm_ver="3.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-3.8', 'B2_CXXSTD': '03,11,14', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-4.0 B2_CXXSTD=11,14 Job 6", "clang++-4.0", packages="clang-4.0 libstdc++-6-dev", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-4.0', 'B2_CXXSTD': '11,14', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-5.0 B2_CXXSTD=11,14,17 Job 7", "clang++-5.0", packages="clang-5.0 libstdc++-7-dev", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-5.0', 'B2_CXXSTD': '11,14,17', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-6.0 B2_CXXSTD=14,17,2a Job 8", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-7 B2_CXXSTD=14,17,2a Job 9", "clang++-7", packages="clang-7 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="xenial", llvm_ver="7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-7', 'B2_CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-8 B2_CXXSTD=14,17,2a Job 10", "clang++-8", packages="clang-8 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="xenial", llvm_ver="8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-8', 'B2_CXXSTD': '14,17,2a', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv),
linux_cxx("B2_TOOLSET=clang-6.0 B2_CXXSTD=03,11,14,17,2a Job 11", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'B2_TOOLSET': 'clang-6.0', 'B2_CXXSTD': '03,11,14,17,2a', 'B2_CXXFLAGS': '-stdlib=libc++', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv),
osx_cxx("B2_TOOLSET=clang B2_CXXSTD=03,11,17 Job 12", "g++", packages="", buildtype="boost", buildscript="drone", environment={'B2_TOOLSET': 'clang', 'B2_CXXSTD': '03,11,17', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv),
linux_cxx("COMMENT=codecov.io B2_TOOLSET=gcc-7 B2_DEFINE Job 13", "g++-7", packages="g++-7", buildtype="b5847f804b-bbb3de2b00", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'codecov.io', 'B2_TOOLSET': 'gcc-7', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv),
linux_cxx("COMMENT=cppcheck Job 14", "g++", packages="binutils-gold gdb libc6-dbg", buildtype="b5847f804b-ed45733e6c", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'cppcheck', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv),
linux_cxx("COMMENT=ubsan B2_VARIANT=variant=debug B2_TOO Job 15", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'ubsan', 'B2_VARIANT': 'variant=debug', 'B2_TOOLSET': 'gcc-8', 'B2_CXXSTD': '03,11,14,17,2a', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1', 'B2_CXXFLAGS': 'cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined', 'B2_LINKFLAGS': 'linkflags=-fsanitize=undefined linkflags=-fno-sanitize-recover=undefined linkflags=-fuse-ld=gold', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv),
linux_cxx("COMMENT=valgrind B2_TOOLSET=clang-6.0 B2_CXXS Job 16", "clang++-6.0", packages="clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev", llvm_os="xenial", llvm_ver="6.0", buildtype="b5847f804b-db180b7bd2", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'valgrind', 'B2_TOOLSET': 'clang-6.0', 'B2_CXXSTD': '03,11,14,17,2a', 'B2_DEFINES': 'define=BOOST_NO_STRESS_TEST=1', 'B2_VARIANT': 'variant=debug', 'B2_TESTFLAGS': 'testing.launcher=valgrind', 'VALGRIND_OPTS': '--error-exitcode=1', 'DRONE_JOB_UUID': '1574bddb75'}, globalenv=globalenv),
linux_cxx("COMMENT=Coverity Scan B2_TOOLSET=gcc Job 17", "g++", packages="binutils-gold gdb libc6-dbg", buildtype="b5847f804b-cce9827eb5", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'Coverity Scan', 'B2_TOOLSET': 'gcc', 'DRONE_JOB_UUID': '0716d9708d'}, globalenv=globalenv),
]
# from https://github.com/boostorg/boost-ci
load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx")

View File

@@ -0,0 +1,129 @@
#!/bin/bash
# Copyright 2020 Rene Rivera, Sam Darwin
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export DRONE_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=$DRONE_BRANCH
export VCS_COMMIT_ID=$DRONE_COMMIT
export GIT_COMMIT=$DRONE_COMMIT
export REPO_NAME=$DRONE_REPO
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/build.sh
elif [ "$DRONE_JOB_BUILDTYPE" == "b5847f804b-bbb3de2b00" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd
cd $BOOST_ROOT/libs/$SELF
ci/travis/codecov.sh
elif [ "$DRONE_JOB_BUILDTYPE" == "b5847f804b-ed45733e6c" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/cppcheck.sh
elif [ "$DRONE_JOB_BUILDTYPE" == "b5847f804b-db180b7bd2" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/valgrind.sh
elif [ "$DRONE_JOB_BUILDTYPE" == "b5847f804b-cce9827eb5" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
if [ -n "${COVERITY_SCAN_NOTIFICATION_EMAIL}" -a \( "$DRONE_BRANCH" = "develop" -o "$DRONE_BRANCH" = "master" \) -a "$DRONE_BUILD_EVENT" = "push" ] ; then
cd $BOOST_ROOT/libs/$SELF
ci/travis/coverity.sh
fi
fi

View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,495 @@
name: GitHub Actions CI
on:
pull_request:
push:
branches:
- master
- develop
- githubactions*
- feature/**
- fix/**
- pr/**
env:
B2_VARIANT: variant=release,debug
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- name: "B2_TOOLSET=gcc-4.8 B2_CXXSTD=03,11 Job 0"
buildtype: "boost"
packages: "g++-4.8"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-4.8"
sources: ""
llvm_os: ""
llvm_ver: ""
b2_toolset: "gcc-4.8"
b2_cxxstd: "03,11"
- name: "B2_TOOLSET=gcc-5 B2_CXXSTD=11 Job 1"
buildtype: "boost"
packages: "g++-5"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-5"
sources: ""
llvm_os: ""
llvm_ver: ""
b2_toolset: "gcc-5"
b2_cxxstd: "11"
- name: "B2_TOOLSET=gcc-6 B2_CXXSTD=11,14 Job 2"
buildtype: "boost"
packages: "g++-6"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-6"
sources: ""
llvm_os: ""
llvm_ver: ""
b2_toolset: "gcc-6"
b2_cxxstd: "11,14"
- name: "B2_TOOLSET=gcc-7 B2_CXXSTD=11,14,17 Job 3"
buildtype: "boost"
packages: "g++-7"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-7"
sources: ""
llvm_os: ""
llvm_ver: ""
b2_toolset: "gcc-7"
b2_cxxstd: "11,14,17"
- name: "B2_TOOLSET=gcc-8 B2_CXXSTD=14,17,2a Job 4"
buildtype: "boost"
packages: "g++-8"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-8"
sources: ""
llvm_os: ""
llvm_ver: ""
b2_toolset: "gcc-8"
b2_cxxstd: "14,17,2a"
- name: "B2_TOOLSET=clang-3.8 B2_CXXSTD=03,11,14 Job 5"
buildtype: "boost"
packages: "clang-3.8 libstdc++-6-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-3.8"
sources: ""
llvm_os: "xenial"
llvm_ver: "3.8"
b2_toolset: "clang-3.8"
b2_cxxstd: "03,11,14"
- name: "B2_TOOLSET=clang-4.0 B2_CXXSTD=11,14 Job 6"
buildtype: "boost"
packages: "clang-4.0 libstdc++-6-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-4.0"
sources: ""
llvm_os: "xenial"
llvm_ver: "4.0"
b2_toolset: "clang-4.0"
b2_cxxstd: "11,14"
- name: "B2_TOOLSET=clang-5.0 B2_CXXSTD=11,14,17 Job 7"
buildtype: "boost"
packages: "clang-5.0 libstdc++-7-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-5.0"
sources: ""
llvm_os: "xenial"
llvm_ver: "5.0"
b2_toolset: "clang-5.0"
b2_cxxstd: "11,14,17"
- name: "B2_TOOLSET=clang-6.0 B2_CXXSTD=14,17,2a Job 8"
buildtype: "boost"
packages: "clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-6.0"
sources: ""
llvm_os: "xenial"
llvm_ver: "6.0"
b2_toolset: "clang-6.0"
b2_cxxstd: "14,17,2a"
- name: "B2_TOOLSET=clang-7 B2_CXXSTD=14,17,2a Job 9"
buildtype: "boost"
packages: "clang-7 libc6-dbg libc++-dev libstdc++-8-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-7"
sources: ""
llvm_os: "xenial"
llvm_ver: "7"
b2_toolset: "clang-7"
b2_cxxstd: "14,17,2a"
- name: "B2_TOOLSET=clang-8 B2_CXXSTD=14,17,2a Job 10"
buildtype: "boost"
packages: "clang-8 libc6-dbg libc++-dev libstdc++-8-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-8"
sources: ""
llvm_os: "xenial"
llvm_ver: "8"
b2_toolset: "clang-8"
b2_cxxstd: "14,17,2a"
- name: "B2_TOOLSET=clang-6.0 B2_CXXSTD=03,11,14,17,2a Job 11"
buildtype: "boost"
packages: "clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-6.0"
sources: ""
llvm_os: "xenial"
llvm_ver: "6.0"
b2_toolset: "clang-6.0"
b2_cxxstd: "03,11,14,17,2a"
b2_cxxflags: "-stdlib=libc++"
- name: "COMMENT=codecov.io B2_TOOLSET=gcc-7 B2_DEFINE Job 13"
buildtype: "b5847f804b-bbb3de2b00"
packages: "g++-7"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-7"
sources: ""
llvm_os: ""
llvm_ver: ""
comment: "codecov.io"
b2_toolset: "gcc-7"
b2_defines: "define=BOOST_NO_STRESS_TEST=1"
- name: "COMMENT=cppcheck Job 14"
buildtype: "b5847f804b-ed45733e6c"
packages: "binutils-gold gdb libc6-dbg"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
comment: "cppcheck"
- name: "COMMENT=ubsan B2_VARIANT=variant=debug B2_TOO Job 15"
buildtype: "boost"
packages: "g++-8"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++-8"
sources: ""
llvm_os: ""
llvm_ver: ""
comment: "ubsan"
b2_variant: "variant=debug"
b2_toolset: "gcc-8"
b2_cxxstd: "03,11,14,17,2a"
b2_defines: "define=BOOST_NO_STRESS_TEST=1"
b2_cxxflags: "cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined"
b2_linkflags: "linkflags=-fsanitize=undefined linkflags=-fno-sanitize-recover=undefined linkflags=-fuse-ld=gold"
ubsan_options: "print_stacktrace=1"
- name: "COMMENT=valgrind B2_TOOLSET=clang-6.0 B2_CXXS Job 16"
buildtype: "b5847f804b-db180b7bd2"
packages: "clang-6.0 libc6-dbg libc++-dev libstdc++-8-dev"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "clang++-6.0"
sources: ""
llvm_os: "xenial"
llvm_ver: "6.0"
comment: "valgrind"
b2_toolset: "clang-6.0"
b2_cxxstd: "03,11,14,17,2a"
b2_defines: "define=BOOST_NO_STRESS_TEST=1"
b2_variant: "variant=debug"
b2_testflags: "testing.launcher=valgrind"
valgrind_opts: "--error-exitcode=1"
- name: "COMMENT=Coverity Scan B2_TOOLSET=gcc Job 17"
buildtype: "b5847f804b-cce9827eb5"
packages: "binutils-gold gdb libc6-dbg"
packages_to_remove: ""
os: "ubuntu-16.04"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
comment: "Coverity Scan"
b2_toolset: "gcc"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
steps:
- name: Check if running in container
if: matrix.container != ''
run: echo "GHA_CONTAINER=${{ matrix.container }}" >> $GITHUB_ENV
- uses: actions/checkout@v2
- name: linux
shell: bash
env:
CXX: ${{ matrix.cxx }}
SOURCES: ${{ matrix.sources }}
LLVM_OS: ${{ matrix.llvm_os }}
LLVM_VER: ${{ matrix.llvm_ver }}
PACKAGES: ${{ matrix.packages }}
PACKAGES_TO_REMOVE: ${{ matrix.packages_to_remove }}
JOB_BUILDTYPE: ${{ matrix.buildtype }}
B2_TOOLSET: ${{ matrix.b2_toolset }}
B2_CXXSTD: ${{ matrix.b2_cxxstd }}
B2_CXXFLAGS: ${{ matrix.b2_cxxflags }}
COMMENT: ${{ matrix.comment }}
B2_DEFINES: ${{ matrix.b2_defines }}
B2_VARIANT: ${{ matrix.b2_variant }}
B2_LINKFLAGS: ${{ matrix.b2_linkflags }}
UBSAN_OPTIONS: ${{ matrix.ubsan_options }}
B2_TESTFLAGS: ${{ matrix.b2_testflags }}
VALGRIND_OPTS: ${{ matrix.valgrind_opts }}
TRAVIS_BRANCH: ${{ github.base_ref }}
TRAVIS_OS_NAME: "linux"
run: |
echo '==================================> SETUP'
echo '==================================> PACKAGES'
set -e
if [ -n "$PACKAGES_TO_REMOVE" ]; then sudo apt-get purge -y $PACKAGES_TO_REMOVE; fi
echo ">>>>> APT: REPO.."
for i in {1..3}; do sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test" && break || sleep 2; done
if test -n "${LLVM_OS}" ; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
if test -n "${LLVM_VER}" ; then
sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS}-${LLVM_VER} main"
else
# Snapshot (i.e. trunk) build of clang
sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS} main"
fi
fi
echo ">>>>> APT: UPDATE.."
sudo -E apt-get -o Acquire::Retries=3 update
if test -n "${SOURCES}" ; then
echo ">>>>> APT: INSTALL SOURCES.."
for SOURCE in $SOURCES; do
sudo -E apt-add-repository ppa:$SOURCE
done
fi
echo ">>>>> APT: INSTALL ${PACKAGES}.."
sudo -E DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -y --no-install-suggests --no-install-recommends install ${PACKAGES}
echo '==================================> INSTALL AND COMPILE'
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}
export VCS_COMMIT_ID=$GITHUB_SHA
export GIT_COMMIT=$GITHUB_SHA
export REPO_NAME=$(basename $GITHUB_REPOSITORY)
export USER=$(whoami)
export CC=${CC:-gcc}
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/build.sh
elif [ "$JOB_BUILDTYPE" == "b5847f804b-bbb3de2b00" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd
cd $BOOST_ROOT/libs/$SELF
ci/travis/codecov.sh
elif [ "$JOB_BUILDTYPE" == "b5847f804b-ed45733e6c" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/cppcheck.sh
elif [ "$JOB_BUILDTYPE" == "b5847f804b-db180b7bd2" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/valgrind.sh
elif [ "$JOB_BUILDTYPE" == "b5847f804b-cce9827eb5" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
if [ -n "${COVERITY_SCAN_NOTIFICATION_EMAIL}" -a \( "$TRAVIS_BRANCH" = "develop" -o "$TRAVIS_BRANCH" = "master" \) -a \("$GITHUB_EVENT_NAME" = "push" -o "$GITHUB_EVENT_NAME" = "cron" \) ] ; then
cd $BOOST_ROOT/libs/$SELF
ci/travis/coverity.sh
fi
fi
osx:
strategy:
fail-fast: false
matrix:
include:
- name: "B2_TOOLSET=clang B2_CXXSTD=03,11,17 Job 12"
buildtype: "boost"
packages: ""
os: "macos-10.15"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
xcode_version: 11.7
b2_toolset: "clang"
b2_cxxstd: "03,11,17"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set DEVELOPER_DIR
if: matrix.xcode_version != ''
run: echo "DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode_version }}.app/Contents/Developer" >> $GITHUB_ENV
- name: Test DEVELOPER_DIR
run: echo $DEVELOPER_DIR
- name: "osx"
shell: bash
env:
CXX: ${{ matrix.cxx }}
SOURCES: ${{ matrix.sources }}
LLVM_OS: ${{ matrix.llvm_os }}
LLVM_VER: ${{ matrix.llvm_ver }}
PACKAGES: ${{ matrix.packages }}
JOB_BUILDTYPE: ${{ matrix.buildtype }}
B2_TOOLSET: ${{ matrix.b2_toolset }}
B2_CXXSTD: ${{ matrix.b2_cxxstd }}
B2_CXXFLAGS: ${{ matrix.b2_cxxflags }}
COMMENT: ${{ matrix.comment }}
B2_DEFINES: ${{ matrix.b2_defines }}
B2_VARIANT: ${{ matrix.b2_variant }}
B2_LINKFLAGS: ${{ matrix.b2_linkflags }}
UBSAN_OPTIONS: ${{ matrix.ubsan_options }}
B2_TESTFLAGS: ${{ matrix.b2_testflags }}
VALGRIND_OPTS: ${{ matrix.valgrind_opts }}
TRAVIS_BRANCH: ${{ github.base_ref }}
TRAVIS_OS_NAME: "osx"
run: |
echo '==================================> SETUP'
set -e
sudo mv /Library/Developer/CommandLineTools /Library/Developer/CommandLineTools.bck
echo '==================================> PACKAGES'
echo '==================================> INSTALL AND COMPILE'
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}
export VCS_COMMIT_ID=$GITHUB_SHA
export GIT_COMMIT=$GITHUB_SHA
export REPO_NAME=$(basename $GITHUB_REPOSITORY)
export USER=$(whoami)
export CC=${CC:-gcc}
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
git clone https://github.com/boostorg/boost-ci.git boost-ci
cp -pr boost-ci/ci boost-ci/.codecov.yml .
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
unset -f cd
fi
export SELF=`basename $REPO_NAME`
export BOOST_CI_TARGET_BRANCH="$TRAVIS_BRANCH"
export BOOST_CI_SRC_FOLDER=$(pwd)
. ./ci/common_install.sh
echo '==================================> SCRIPT'
cd $BOOST_ROOT/libs/$SELF
ci/travis/build.sh
fi

View File

@@ -0,0 +1,185 @@
# Copyright 2016 Peter Dimov
# Copyright 2017 - 2019 James E. King III
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
#
# Generic Travis CI build script for boostorg repositories
# See: https://github.com/boostorg/boost-ci
#
# Instructions for customizing this script for your library:
#
# 1. Customize the compilers and language levels you want in the 'jobs'.
# 2. If you have more than include/, src/, test/, example/, examples/, or
# tools/ directories, modify your Travis CI project and add the environment
# variable DEPINST. For example if your build uses code in "bench/" and
# "fog/" directories, then set DEPINST to the following:
# --include bench --include fog
# 3. If you want to enable Coverity Scan, you need to provide the environment
# variables COVERITY_SCAN_TOKEN and COVERITY_SCAN_NOTIFICATION_EMAIL in
# your github settings.
# 4. Enable pull request builds in your boostorg/<library> account.
#
# That's it - the scripts will do everything else for you.
dist: xenial
language: cpp
env:
global:
# see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
# to use the default for a given environment, comment it out; recommend you build debug and release however..
# - B2_ADDRESS_MODEL=address-model=64,32
# - B2_LINK=link=shared,static
# - B2_THREADING=threading=multi,single
- B2_VARIANT=variant=release,debug
install:
- git clone https://github.com/boostorg/boost-ci.git boost-ci
- cp -pr boost-ci/ci boost-ci/.codecov.yml .
- source ci/travis/install.sh
addons:
apt:
packages:
- binutils-gold
- gdb
- libc6-dbg
branches:
only:
- develop
- master
script:
- cd $BOOST_ROOT/libs/$SELF
- ci/travis/build.sh
#
# Default toolsets in Ubuntu
#
# trusty xenial bionic
# 14.04 16.04 18.04
# ------ ------ ------
# clang 3.4 3.8 6.0
# gcc 4.8.2 5.3.1 7.3.0
#
anchors:
clang-38: &clang-38 { apt: { packages: [ "clang-3.8",
"libstdc++-6-dev" ], sources: [ "llvm-toolchain-xenial-3.8",
"ubuntu-toolchain-r-test" ] } }
clang-4: &clang-4 { apt: { packages: [ "clang-4.0",
"libstdc++-6-dev" ], sources: [ "llvm-toolchain-xenial-4.0",
"ubuntu-toolchain-r-test" ] } }
clang-5: &clang-5 { apt: { packages: [ "clang-5.0",
"libstdc++-7-dev" ], sources: [ "llvm-toolchain-xenial-5.0",
"ubuntu-toolchain-r-test" ] } }
clang-6: &clang-6 { apt: { packages: [ "clang-6.0",
"libc6-dbg",
"libc++-dev",
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-6.0",
"ubuntu-toolchain-r-test" ] } }
clang-7: &clang-7 { apt: { packages: [ "clang-7",
"libc6-dbg",
"libc++-dev",
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-7",
"ubuntu-toolchain-r-test" ] } }
clang-8: &clang-8 { apt: { packages: [ "clang-8",
"libc6-dbg",
"libc++-dev",
"libstdc++-8-dev" ], sources: [ "llvm-toolchain-xenial-8",
"ubuntu-toolchain-r-test" ] } }
gcc-48: &gcc-48 { apt: { packages: [ "g++-4.8" ] } }
gcc-5: &gcc-5 { apt: { packages: [ "g++-5" ] } }
gcc-6: &gcc-6 { apt: { packages: [ "g++-6" ], sources: [ "ubuntu-toolchain-r-test" ] } }
gcc-7: &gcc-7 { apt: { packages: [ "g++-7" ], sources: [ "ubuntu-toolchain-r-test" ] } }
gcc-8: &gcc-8 { apt: { packages: [ "g++-8" ], sources: [ "ubuntu-toolchain-r-test" ] } }
jobs:
allow_failures:
- env:
- COPY="all the environment settings from your job"
include:
# libstdc++
- { os: "linux", env: [ "B2_TOOLSET=gcc-4.8", "B2_CXXSTD=03,11" ], addons: *gcc-48 }
- { os: "linux", env: [ "B2_TOOLSET=gcc-5", "B2_CXXSTD=11" ], addons: *gcc-5 }
- { os: "linux", env: [ "B2_TOOLSET=gcc-6", "B2_CXXSTD=11,14" ], addons: *gcc-6 }
- { os: "linux", env: [ "B2_TOOLSET=gcc-7", "B2_CXXSTD=11,14,17" ], addons: *gcc-7 }
- { os: "linux", env: [ "B2_TOOLSET=gcc-8", "B2_CXXSTD=14,17,2a" ], addons: *gcc-8 }
- { os: "linux", env: [ "B2_TOOLSET=clang-3.8", "B2_CXXSTD=03,11,14" ], addons: *clang-38 }
- { os: "linux", env: [ "B2_TOOLSET=clang-4.0", "B2_CXXSTD=11,14" ], addons: *clang-4 }
- { os: "linux", env: [ "B2_TOOLSET=clang-5.0", "B2_CXXSTD=11,14,17" ], addons: *clang-5 }
- { os: "linux", env: [ "B2_TOOLSET=clang-6.0", "B2_CXXSTD=14,17,2a" ], addons: *clang-6 }
- { os: "linux", env: [ "B2_TOOLSET=clang-7", "B2_CXXSTD=14,17,2a" ], addons: *clang-7 }
- { os: "linux", env: [ "B2_TOOLSET=clang-8", "B2_CXXSTD=14,17,2a" ], addons: *clang-8 }
# libc++
- { os: "linux", env: [ "B2_TOOLSET=clang-6.0", "B2_CXXSTD=03,11,14,17,2a",
"B2_CXXFLAGS=-stdlib=libc++" ], addons: *clang-6 }
- { os: "osx" , env: [ "B2_TOOLSET=clang", "B2_CXXSTD=03,11,17" ] }
# to enable Intel ICC define INTEL_ICC_SERIAL_NUMBER and the following:
# - { os: "linux", env: [ "B2_TOOLSET=intel-linux", "B2_CXXSTD=11,14,17" ], addons: *gcc-7,
# script: cd $BOOST_ROOT/libs/$SELF && ci/travis/intelicc.sh }
- os: linux
env:
- COMMENT=codecov.io
- B2_TOOLSET=gcc-7
- B2_DEFINES="define=BOOST_NO_STRESS_TEST=1"
addons: *gcc-7
script:
- pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd
- cd $BOOST_ROOT/libs/$SELF
- ci/travis/codecov.sh
- os: linux
env:
- COMMENT=cppcheck
script:
- cd $BOOST_ROOT/libs/$SELF
- ci/travis/cppcheck.sh
- os: linux
env:
- COMMENT=ubsan
- B2_VARIANT=variant=debug
- B2_TOOLSET=gcc-8
- B2_CXXSTD=03,11,14,17,2a
- B2_DEFINES="define=BOOST_NO_STRESS_TEST=1"
- B2_CXXFLAGS="cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined"
- B2_LINKFLAGS="linkflags=-fsanitize=undefined linkflags=-fno-sanitize-recover=undefined linkflags=-fuse-ld=gold"
- UBSAN_OPTIONS=print_stacktrace=1
addons: *gcc-8
- os: linux
env:
- COMMENT=valgrind
- B2_TOOLSET=clang-6.0
- B2_CXXSTD=03,11,14,17,2a
- B2_DEFINES="define=BOOST_NO_STRESS_TEST=1"
- B2_VARIANT=variant=debug
- B2_TESTFLAGS=testing.launcher=valgrind
- VALGRIND_OPTS=--error-exitcode=1
addons: *clang-6
script:
- cd $BOOST_ROOT/libs/$SELF
- ci/travis/valgrind.sh
#################### Jobs to run on pushes to master, develop ###################
# Coverity Scan
- os: linux
if: (env(COVERITY_SCAN_NOTIFICATION_EMAIL) IS present) AND (branch IN (develop, master)) AND (type IN (cron, push))
env:
- COMMENT="Coverity Scan"
- B2_TOOLSET=gcc
script:
- cd $BOOST_ROOT/libs/$SELF
- ci/travis/coverity.sh
notifications:
email:
false

View File

@@ -0,0 +1,22 @@
# Copyright 2018 Glen Joseph Fernandes
# (glenjofe@gmail.com)
#
# Distributed under the Boost Software License, Version 1.0.
# (http://www.boost.org/LICENSE_1_0.txt)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_concept_check VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_concept_check INTERFACE)
add_library(Boost::concept_check ALIAS boost_concept_check)
target_include_directories(boost_concept_check INTERFACE include)
target_link_libraries(boost_concept_check INTERFACE
Boost::config
Boost::preprocessor
Boost::static_assert
Boost::type_traits
)

View File

@@ -0,0 +1,10 @@
# Boost.ConceptCheck Library Jamfile
#
# Copyright (c) 2018 James E. King III
#
# Use, modification, and distribution are subject to the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# please order by name to ease maintenance
build-project test ;

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,34 @@
ConceptCheck, part of collection of the [Boost C++ Libraries](http://github.com/boostorg),
allows one to add explicit statement and checking of concepts in the style of the proposed C++ language extension.
### License
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
### Properties
* C++03
* Header-only
### Build Status
Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
[`master`](https://github.com/boostorg/concept_check/tree/master) | [![Build Status](https://travis-ci.org/boostorg/concept_check.svg?branch=master)](https://travis-ci.org/boostorg/concept_check) | [![Build status](https://ci.appveyor.com/api/projects/status/yoj8ae7yopd903i9/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/concept_check-gp9xw/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)](https://codecov.io/gh/boostorg/concept_check/branch/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)](http://www.boost.org/doc/libs/master/doc/html/concept_check.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/concept_check.html)
[`develop`](https://github.com/boostorg/concept_check/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/concept_check.svg?branch=develop)](https://travis-ci.org/boostorg/concept_check) | [![Build status](https://ci.appveyor.com/api/projects/status/yoj8ae7yopd903i9/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/concept_check-gp9xw/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)](https://codecov.io/gh/boostorg/concept_check/branch/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)](http://www.boost.org/doc/libs/develop/doc/html/concept_check.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/concept_check.html)
### Directories
| Name | Purpose |
| ----------- | ------------------------------ |
| `doc` | documentation |
| `include` | headers |
| `test` | unit tests |
### More information
* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-concept_check)
* [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.
* 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](http://www.boost.org/LICENSE_1_0.txt).
* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[concept_check]` tag at the beginning of the subject line.

View File

@@ -0,0 +1,126 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright (C) 2017 - 2019 James E. King III
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
#
# Generic Appveyor build script for boostorg repositories
# See: https://github.com/boostorg/boost-ci/
#
# Instructions for customizing this script for your library:
#
# 1. Customize the compilers and language levels you want.
# 2. If you have more than include/, src/, test/, example/, examples/,
# benchmark/ or tools/ directories, set the environment variable DEPINST.
# For example if your build uses code in "bench/" and "fog/" directories:
# - DEPINST: --include bench --include fog
# 3. Enable pull request builds in your boostorg/<library> account.
#
# That's it - the script will do everything else for you.
#
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- develop
- master
matrix:
# Adding MAYFAIL to any matrix job allows it to fail but the build stays green:
allow_failures:
- MAYFAIL: true
environment:
global:
# see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
# to use the default for a given environment, comment it out; recommend you build debug and release however:
# on Windows it is important to exercise all the possibilities, especially shared vs static, however most
# libraries that care about this exercise it in their Jamfiles...
# B2_ADDRESS_MODEL: address-model=64,32
# B2_LINK: link=shared,static
# B2_THREADING: threading=multi,single
B2_VARIANT: variant=release,debug
matrix:
- FLAVOR: Visual Studio 2017 C++2a Strict
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_ADDRESS_MODEL: address-model=64
B2_CXXFLAGS: cxxflags=-permissive-
B2_CXXSTD: latest # 2a
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2017 C++17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_ADDRESS_MODEL: address-model=64
B2_CXXSTD: 17
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2017 C++14 (Default)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_ADDRESS_MODEL: address-model=64,32
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2015 C++14 (Default)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_ADDRESS_MODEL: address-model=64,32
B2_TOOLSET: msvc-14.0
- FLAVOR: Visual Studio 2010, 2012, 2013
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0
- FLAVOR: cygwin (32-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin\bin;
B2_ADDRESS_MODEL: address-model=32
B2_CXXSTD: 03,11
# https://github.com/boostorg/test/issues/144
B2_DEFINES: define=_POSIX_C_SOURCE=200112L
B2_THREADING: threadapi=pthread
B2_TOOLSET: gcc
- FLAVOR: cygwin (64-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: address-model=64
B2_CXXSTD: 11,17
# https://github.com/boostorg/test/issues/144
B2_DEFINES: define=_POSIX_C_SOURCE=200112L define=__USE_ISOC99
B2_THREADING: threadapi=pthread
B2_TOOLSET: gcc
- FLAVOR: mingw32
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARCH: i686
B2_ADDRESS_MODEL: address-model=32
B2_CXXSTD: 03,11
SCRIPT: ci\appveyor\mingw.bat
- FLAVOR: mingw64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARCH: x86_64
B2_ADDRESS_MODEL: address-model=64
B2_CXXSTD: 11,17
B2_DEFINES: define=__USE_ISOC99
SCRIPT: ci\appveyor\mingw.bat
install:
- set SELF=%APPVEYOR_PROJECT_NAME:-=_%
- git clone https://github.com/boostorg/boost-ci.git C:\boost-ci
- xcopy /s /e /q /i C:\boost-ci\ci .\ci
- ci\appveyor\install.bat
build: off
test_script:
- set SELF=%APPVEYOR_PROJECT_NAME:-=_%
- PATH=%ADDPATH%%PATH%
# The definition of B2_TOOLCXX omits B2_CXXSTD= if it was not defined above
- IF NOT DEFINED B2_CXXSTD (SET B2_TOOLCXX=toolset=%B2_TOOLSET%) ELSE (SET B2_TOOLCXX=toolset=%B2_TOOLSET% cxxstd=%B2_CXXSTD%)
# Echo the complete build command to the build log
- IF NOT DEFINED SCRIPT (ECHO b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3)
# Now go build...
- IF DEFINED SCRIPT (call libs\%SELF%\%SCRIPT%) ELSE (b2 libs/%SELF:\=/% %B2_TOOLCXX% %B2_CXXFLAGS% %B2_DEFINES% %B2_THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3)

View File

@@ -0,0 +1,14 @@
#include <vector>
#include <complex>
#include "algorithm"
int main()
{
std::vector<std::complex<float> > v;
std_::stable_sort(v.begin(), v.end());
}
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -0,0 +1,65 @@
<HTML>
<!-- Copyright (c) Jeremy Siek 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<Head>
<Title>Boost Concept Checking Library: Bibliography</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../boost.png"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<H2>Bibliography</H2>
<DL COMMapCT>
<DD><P></P><DT><a name="alexandrescu99:_better_templ_error_messag">1</a>
<DD>Andrei Alexandrescu<BR>
<EM>Better Template Error Messages</EM>.<BR>
C/C++ Users Journal, March, 1999.
<DD><P></P><DT><a name="stroustrup94:_design_evolution">2</a>
<DD>Bjarne Stroustrup<BR>
<EM>Design and Evolution of C++</EM>.<BR>
Addison-Wesley, 1994
<P></P><DT><A NAME="austern99:_gener_progr_stl">3</A>
<DD>
M.&nbsp;H. Austern.
<BR><EM>Generic Programming and the STL</EM>.
<BR>Professional computing series. Addison-Wesley, 1999.
<P></P><DT><A NAME="IB-H965502">4</A>
<DD>
David R. Musser and Atul Saini
<BR><EM>STL Tutorial and Reference Guide</EM>.
<BR>Professional computing series. Addison-Wesley, 1996.
<P></P><DT><A NAME="stepa.lee-1994:the.s:TR">5</A>
<DD>
A. A. Stepanov and M. Lee
<BR><EM>The Standard Template Library</EM>.
<BR>ISO Programming Language C++ Project, May 1994.
<BR>X3J16/94-0095, WG21/N0482
</DL>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>(<A
HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)
Andrew Lumsdaine</A>(<A HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
</TD></TR></TABLE>
</BODY>
</HTML>

View File

@@ -0,0 +1,330 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) 2000 Jeremy Siek and Andrew Lumsdaine, 2007 David Abrahams -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Concept Check Library</title>
<link rel="stylesheet" href="../../rst.css" type="text/css" />
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h1>The Boost Concept Check Library (BCCL)</h1>
<blockquote>
The Concept Check library allows one to add explicit statement and
checking of <a href=
"http://www.boost.org/more/generic_programming.html#concept">concepts</a> in the style
of the <a href=
"http://www.generic-programming.org/languages/conceptcpp/specification/">proposed
C++ language extension</a>.
</blockquote>
<h2><a name="sec:concept-checking" id="sec:concept-checking"></a>Synopsis</a></h2>
<p>Generic programming in C++ is characterized by the use of template
parameters to represent abstract data types (or “<a href=
"http://www.boost.org/more/generic_programming.html#concept">concepts</a>”). However, the
C++ language itself does not provide a mechanism for the writer of a class
or function template to explicitly state the concept that the user-supplied
template argument should model (or conform to). Template parameters are
commonly named after the concept they're required to model as a hint to the
user, and to make the concept requirements explicit in code. However, the
compiler doesn't treat these special names specially: a parameter named
<code>RandomAccessIterator</code> is no different to the compiler than one
named <code>T</code>. Furthermore,</p>
<ul>
<li>Compiler error messages resulting from incorrect template arguments
can be particularly difficult to decipher. Often times the error does not
point to the location of the template call-site, but instead exposes the
internals of the template, which the user should never have to see.</li>
<li>Without checking from the compiler, the documented requirements are
oftentimes vague, incorrect, or nonexistent, so a user cannot know
exactly what kind of arguments are expected.</li>
<li>The documented concept requirements may not fully <i>cover</i> the
needs of the actual template, meaning the user could get a compiler error
even though the supplied template arguments meet the documented
requirements.</li>
<li>The documented concept requirements may be too stringent, requiring
more than is really needed by the template.</li>
<li>Concept names in code may drift out-of-sync with the documented
requirements.</li>
</ul><p>The Boost Concept Checking Library provides:
<ul>
<li>A mechanism for inserting compile-time checks on template parameters
at their point of use.</li>
<li>A framework for specifying concept requirements through concept
checking classes.</li>
<li>A mechanism for verifying that concept requirements cover the
template.</li>
<li>A suite of concept checking classes and archetype classes that match
the concept requirements in the C++ Standard Library.</li>
<li>An alternative to the use of traits classes for accessing associated
types that mirrors the syntax proposed for the next C++ standard.</li>
</ul><p>The mechanisms use standard C++ and introduce no run-time overhead.
The main cost of using the mechanism is in compile-time.</p>
<p><strong>Every programmer writing class or function templates ought to
make concept checking a normal part of their code writing routine.</strong>
A concept check should be inserted for each template parameter in a
component's public interface. If the concept is one of the ones from the
Standard Library, then simply use the matching concept checking class in
the BCCL. If not, then write a new concept checking class - after all, they
are typically only a few lines long. For new concepts, a matching archetype
class should also be created, which is a minimal skeleton-implementation of
the concept</p>
<p>The documentation is organized into the following sections.</p>
<ol>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#motivating-example">Motivating Example</a></li>
<li><a href="#history">History</a></li>
<li><a href="#publications">Publications</a></li>
<li><a href="#acknowledgements">Acknowledgements</a></li>
<li><a href="./using_concept_check.htm">Using Concept Checks</a></li>
<li><a href="creating_concepts.htm">Creating Concept Checking
Classes</a></li>
<li><a href="./concept_covering.htm">Concept Covering and
Archetypes</a></li>
<li><a href="./prog_with_concepts.htm">Programming With Concepts</a></li>
<li><a href="./implementation.htm">Implementation</a></li>
<li><a href="./reference.htm">Reference</a></li>
</ol>
<p><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a> contributed this
library. <a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a> managed
the formal review. <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
Abrahams</a> contributed a rewrite that updated syntax to be more
compatible with proposed syntax for concept support the C++ core
language.</p>
<h2><a name="introduction" id="introduction">Introduction</a></h2><p>A
<i>concept</i> is a set of requirements (valid expressions, associated
types, semantic invariants, complexity guarantees, etc.) that a type must
fulfill to be correctly used as arguments in a call to a generic algorithm.
In C++, concepts are represented by formal template parameters to function
templates (generic algorithms). However, C++ has no explicit mechanism for
representing concepts—template parameters are merely placeholders. By
convention, these parameters are given names corresponding to the concept
that is required, but a C++ compiler does not enforce compliance to the
concept when the template parameter is bound to an actual type.
<p>Naturally, if a generic algorithm is invoked with a type that does not
fulfill at least the syntactic requirements of the concept, a compile-time
error will occur. However, this error will not <i>per se</i> reflect the
fact that the type did not meet all of the requirements of the concept.
Rather, the error may occur deep inside the instantiation hierarchy at the
point where an expression is not valid for the type, or where a presumed
associated type is not available. The resulting error messages are largely
uninformative and basically impenetrable.</p>
<p>What is required is a mechanism for enforcing
“concept safety” at (or close to) the point
of instantiation. The Boost Concept Checking Library uses some standard C++
constructs to enforce early concept compliance and that provides more
informative error messages upon non-compliance.</p>
<p>Note that this technique only addresses the syntactic requirements of
concepts (the valid expressions and associated types). We do not address
the semantic invariants or complexity guarantees, which are also part of
concept requirements..</p>
<h2><a name="motivating-example" id="motivating-example">Motivating
Example</a></h2>
<p>We present a simple example to illustrate incorrect usage of a template
library and the resulting error messages. In the code below, the generic
<tt>std::stable_sort()</tt> algorithm from the Standard Template Library
(STL)[<a href="bibliography.htm#austern99:_gener_progr_stl">3</a>, <a href=
"bibliography.htm#IB-H965502">4</a>,<a href=
"bibliography.htm#stepa.lee-1994:the.s:TR">5</a>] is applied to a linked
list.</p>
<pre>
<a href="./bad_error_eg.cpp">bad_error_eg.cpp</a>:
<font color="gray">1</font> #include &lt;vector&gt;
<font color="gray">2</font color="gray"> #include &lt;complex&gt;
<font color="gray">3</font color="gray"> #include &lt;algorithm&gt;
<font color="gray">4</font color="gray">
<font color="gray">5</font color="gray"> int main()
<font color="gray">6</font color="gray"> {
<font color="gray">7</font color="gray"> std::vector&lt;std::complex&lt;float&gt; &gt; v;
<font color="gray">8</font color="gray"> std::stable_sort(v.begin(), v.end());
<font color="gray">9</font color="gray"> }
</pre>
<p>Here, the <tt>std::stable_sort()</tt> algorithm is prototyped as
follows:</p>
<pre>
template &lt;class RandomAccessIterator&gt;
void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
</pre>
<p>Attempting to compile this code with Gnu C++ produces the following
compiler error:</p>
<pre>
/usr/include/c++/4.1.2/bits/stl_algo.h: In function void std::
__insertion_sort(_RandomAccessIterator, _RandomAccessIterator) [with
_RandomAccessIterator = __gnu_cxx::__normal_iterator&lt;std::complex&lt;float
&gt;*, std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;std::complex&lt;
float&gt; &gt; &gt; &gt;]:
/usr/include/c++/4.1.2/bits/stl_algo.h:3066: instantiated from void
std::__inplace_stable_sort(_RandomAccessIterator,
_RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::
__normal_iterator&lt;std::complex&lt;float&gt;*, std::vector&lt;std::complex&lt;
float&gt;, std::allocator&lt;std::complex&lt;float&gt; &gt; &gt; &gt;]
/usr/include/c++/4.1.2/bits/stl_algo.h:3776: instantiated from void
std::stable_sort(_RandomAccessIterator, _RandomAccessIterator) [with
_RandomAccessIterator = __gnu_cxx::__normal_iterator&lt;std::complex&lt;float
&gt;*, std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;std::complex&lt;
float&gt; &gt; &gt; &gt;]
bad_error_eg.cpp:8: instantiated from here
/usr/include/c++/4.1.2/bits/stl_algo.h:2277: error: no match for
operator&lt; in __val &lt; __first. __gnu_cxx::__normal_iterator&lt;
_Iterator, _Container&gt;::operator* [with _Iterator = std::complex&lt;float
&gt;*, _Container = std::vector&lt;std::complex&lt;float&gt;, std::allocator&lt;
std::complex&lt;float&gt; &gt; &gt;]()
</pre>
<p>In this case, the fundamental error is
that <tt>std:complex&lt;float&gt;</tt> does not model the <a href=
"http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>
concept. Unfortunately, there is nothing in the error message to
indicate that to the user.</p>
<p>The error may be obvious to a C++ programmer having enough
experience with template libraries, but there are several reasons
why this message could be hard for the uninitiated to
understand:</p>
<ol>
<li>There is no textual correlation between the error message and the
documented requirements for <tt>std::stable_sort()</tt> and for <a href=
"http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>.</li>
<li>The error message is overly long, listing functions internal
to the STL (e.g. <code>__insertion_sort</code>) that the user
does not (and should not!) know or care about.</li>
<li>With so many internal library functions listed in the error message,
the programmer could easily infer that the problem is in the library,
rather than in his or her own code.</li>
</ol>
<p>The following is an example of what we might expect from a more
informative message (and is in fact what the Boost Concept Checking Library
produces):</p>
<pre>
boost/concept_check.hpp: In destructor boost::LessThanComparable&lt;TT&gt;::~
LessThanComparable() [with TT = std::complex&lt;float&gt;]:
boost/concept/detail/general.hpp:29: instantiated from static void boost::
concepts::requirement&lt;Model&gt;::failed() [with Model = boost::
LessThanComparable&lt;std::complex&lt;float&gt; &gt;]
boost/concept/requires.hpp:30: instantiated from boost::_requires_&lt;void
(*)(boost::LessThanComparable&lt;std::complex&lt;float&gt; &gt;)&gt;
bad_error_eg.cpp:8: instantiated from here
boost/concept_check.hpp:236: error: no match for operator&lt; in ((boost::
LessThanComparable&lt;std::complex&lt;float&gt; &gt;*)this)-&gt;boost::
LessThanComparable&lt;std::complex&lt;float&gt; &gt;::a &lt; ((boost::
LessThanComparable&lt;std::complex&lt;float&gt; &gt;*)this)-&gt;boost::
LessThanComparable&lt;std::complex&lt;float&gt; &gt;::b
</pre>
<p>This message rectifies several of the shortcomings of the standard error
messages.</p>
<ul>
<li>The message refers explicitly to concepts that the user can look up
in the STL documentation (<a href=
"http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a>).</li>
<li>The error message is now much shorter and does not reveal
internal STL functions, nor indeed does it even point
to <code>std::stable_sort</code>.</li>
<li>The presence of <tt>concept_check.hpp</tt> in the error message
alerts the user to the fact that the error lies in the user code and not
in the library implementation.</li>
</ul>
<h2><a name="history" id="history">History</a></h2>
<p>The first version of this concept checking system was developed
by Jeremy Siek while working at SGI in their C++ compiler and
library group. That version is now part of the SGI STL
distribution. The system originally introduced as the boost concept
checking library differs from concept checking in the SGI STL in
that the definition of concept checking classes was greatly
simplified, at the price of less helpful verbiage in the error
messages. In 2006 the system was rewritten (preserving backward
compatibility) by Dave Abrahams to be easier to use, more similar to
the proposed concept support the C++ core language, and to give
better error messages.
</p>
<h2><a name="publications" id="publications">Publications</a></h2>
<ul>
<li><a href="http://www.oonumerics.org/tmpw00/">C++ Template Workshop
2000</a>, Concept Checking</li>
</ul>
<h2><a name="acknowledgements" id=
"acknowledgements">Acknowledgements</a></h2><p>The idea to use function
pointers to cause instantiation is due to Alexander Stepanov. We are not sure
of the origin of the idea to use expressions to do up-front checking of
templates, but it did appear in D&amp;E[ <a href=
"bibliography.htm#stroustrup94:_design_evolution">2</a>]. Thanks to Matt
Austern for his excellent documentation and organization of the STL
concepts, upon which these concept checks are based. Thanks to Boost
members for helpful comments and reviews.
<p><a href="./using_concept_check.htm">Next: Using Concept
Checks</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,125 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<title>Concept Covering and Archetypes</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="../../rst.css" type="text/css" />
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="concept-covering" id="concept-covering">Concept Covering and
Archetypes</a></h2>
<p>We have discussed how it is important to select the minimal requirements
(concepts) for the inputs to a component, but it is equally important to
verify that the chosen concepts <i>cover</i> the algorithm. That is, any
possible user error should be caught by the concept checks and not let slip
through. Concept coverage can be verified through the use of <i>archetype
classes</i>. An archetype class is an exact implementation of the interface
associated with a particular concept. The run-time behavior of the
archetype class is not important, the functions can be left empty. A simple
test program can then be compiled with the archetype classes as the inputs
to the component. If the program compiles then one can be sure that the
concepts cover the component. The following code shows the archetype class
for the <a href="http://www.boost.org/sgi/stl/InputIterator.html">Input
Iterator</a> concept. Some care must be taken to ensure that the archetype
is an exact match to the concept. For example, the concept states that the
return type of <tt>operator*()</tt> must be convertible to the value type.
It does not state the more stringent requirement that the return type be
<tt>T&amp;</tt> or <tt>const T&amp;</tt>. That means it would be a mistake
to use <tt>T&amp;</tt> or <tt>const T&amp;</tt> for the return type of the
archetype class. The correct approach is to create an artificial return
type that is convertible to <tt>T</tt>, as we have done here with
<tt>reference</tt>. The validity of the archetype class test is completely
dependent on it being an exact match with the concept, which must be
verified by careful (manual) inspection.</p>
<pre>
template &lt;class T&gt;
class input_iterator_archetype
{
private:
typedef input_iterator_archetype self;
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
struct reference {
operator const value_type&amp;() const { return static_object&lt;T&gt;::get(); }
};
typedef const T* pointer;
typedef std::ptrdiff_t difference_type;
self&amp; operator=(const self&amp;) { return *this; }
bool operator==(const self&amp;) const { return true; }
bool operator!=(const self&amp;) const { return true; }
reference operator*() const { return reference(); }
self&amp; operator++() { return *this; }
self operator++(int) { return *this; }
};
</pre>
<p>Generic algorithms are often tested by being instantiated with a number
of common input types. For example, one might apply
<tt>std::stable_sort()</tt> with basic pointer types as the iterators.
Though appropriate for testing the run-time behavior of the algorithm, this
is not helpful for ensuring concept coverage because C++ types never match
particular concepts exactly. Instead, they often provide more than the
minimal functionality required by any one concept. Even though the function
template has concept checks, and compiles with a given type, the checks may
still fall short of covering all the functionality that is actually used.
This is why it is important to compile with archetype classes in addition
to testing with common input types.</p>
<p>The following is an excerpt from <a href=
"./stl_concept_covering.cpp"><tt>stl_concept_covering.cpp</tt></a> that
shows how archetypes can be used to check the requirement documentation for
<a href=
"http://www.boost.org/sgi/stl/stable_sort.html"><tt>std::stable_sort()</tt></a>.
In this case, it looks like the <a href=
"../utility/CopyConstructible.html">CopyConstructible</a> and <a href=
"../utility/Assignable.html">Assignable</a> requirements were forgotten in
the SGI STL documentation (try removing those archetypes). The Boost
archetype classes have been designed so that they can be layered. In this
example the value type of the iterator is composed out of three archetypes.
In the <a href="reference.htm#basic-archetype">archetype class
reference</a>, template parameters named <tt>Base</tt> indicate where the
layered archetype paradigm can be used.</p>
<pre>
{
typedef less_than_comparable_archetype&lt;
sgi_assignable_archetype&lt;&gt; &gt; ValueType;
random_access_iterator_archetype&lt;ValueType&gt; ri;
std::stable_sort(ri, ri);
}
</pre>
<p><a href="./prog_with_concepts.htm">Next: Programming with
Concepts</a><br />
<a href="./creating_concepts.htm">Prev: Creating Concept Checking
Classes</a><br />
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,157 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<title>Creating Concept Checking Classes</title>
<link rel="stylesheet" href="../../rst.css" type="text/css" />
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="creating-concept-checks" id="creating-concept-checks">Creating
Concept Checking Classes</a></h2>
<p>As an example of how to create a concept checking class template, we
look at how to create the corresponding checks for the <a href=
"http://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a> concept.
The complete definition is here:</p>
<pre>
template &lt;class X&gt;
struct InputIterator
: Assignable&lt;X&gt;, EqualityComparable&lt;X&gt;
{
private:
typedef std::iterator_traits&lt;X&gt; t;
public:
typedef typename t::value_type value_type;
typedef typename t::difference_type difference_type;
typedef typename t::reference reference;
typedef typename t::pointer pointer;
typedef typename t::iterator_category iterator_category;
BOOST_CONCEPT_ASSERT((SignedInteger&lt;difference_type&gt;));
BOOST_CONCEPT_ASSERT((Convertible&lt;iterator_category, std::input_iterator_tag&gt;));
BOOST_CONCEPT_USAGE(InputIterator)
{
X j(i); <font color=
"green">// require copy construction</font>
same_type(*i++,v); <font color=
"green">// require postincrement-dereference returning value_type</font>
X&amp; x = ++j; <font color=
"green">// require preincrement returning X&amp;</font>
}
private:
X i;
value_type v;
<font color=
"green">// Type deduction will fail unless the arguments have the same type.</font>
template &lt;typename T&gt;
void same_type(T const&amp;, T const&amp;);
};
</pre>
<h3>Walkthrough</h3>
<p>First, as a convention we name the concept checking class after the
concept. Next, since InputIterator is a refinement of Assignable and
EqualityComparable, we derive its concept checking class from the checking
classes for those other concepts. The library will automatically check for
conformance to Assignable and EqualityComparable whenever it checks the
InputIterator concept.</p>
<p>Next, we declare the concept's <a href=
"http://www.boost.org/more/generic_programming.html#associated_type">associated types</a>
as member typedefs. The associated difference type is required to be a
signed integer, and the iterator category has to be convertible to
std::input_iterator_tag, so we assert those relationships. The syntax for
accessing associated types through the concept-checking template mirrors
the <a href=
"http://www.generic-programming.org/languages/conceptcpp/">proposed</a>
syntax for associated type access in C++0x Finally, we use the
<code>BOOST_CONCEPT_USAGE</code> macro to declare the function that
exercises all the concept's valid expressions. Note that at this point you
may sometimes need to be a little creative: for example, to check that
<code>*i++</code> returns the iterator's value type, we pass both values to
the <code>same_type</code> member function template, which requires both
arguments to have the same type, modulo references and cv-qualification.
It's an imperfect check, but it's better than nothing.</p>
<h3>Values for Usage Patterns Should Be Data Members</h3>
<p>You may be wondering why we declared <code>i</code> and <code>v</code>
as data members in the example above. Why didn't we simply write the
following?</p>
<pre>
BOOST_CONCEPT_USAGE(InputIterator)
{
X i; <font color=
"green">// create the values we need</font>
value_type v;
X j(i); <font color=
"green">// require copy construction</font>
same_type(*i++,v); <font color=
"green">// require postincrement-dereference returning value_type</font>
X&amp; x = ++j; <font color=
"green">// require preincrement returning X&amp;</font>
}
</pre>
<p>Unfortunately, that code wouldn't have worked out so well, because it
unintentionally imposes the requirement that <code>X</code> and its value
type are both default-constructible. On the other hand, since instances of
the <code>InputIterator</code> template will never be constructed, the
compiler never has to check how its data members will be constructed (C++
Standard Section 14.7.1 9). For that reason you should <strong>always
declare values needed for usage patterns as data members</strong>.</p>
<p>These sorts of errors in concept definitions can be detected by the use
of <a href="concept_covering.htm">Concept Archetypes</a>, but it's always
better to avoid them pre-emptively.</p>
<h3>Similarity to Proposed C++0x Language Support for Concepts</h3>
<p>This library's syntaxes for concept refinement and for access of
associated types mirrors the corresponding <a href=
"http://www.generic-programming.org/languages/conceptcpp/">proposed</a>
syntaxes in C++0x. However, C++0x will use
“signatures” rather than usage patterns to
describe the valid operations on types participating in a concept, so when
converting your concept checking classes into language-supported concepts,
you'll need to translate your usage function into a series of
signatures.</p>
<p><a href="./concept_covering.htm">Next: Concept Covering and
Archetypes</a><br />
<a href="./using_concept_check.htm">Prev: Using Concept
Checks</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,14 @@
project boost/concepts ;
import boostbook : boostbook ;
boostbook concepts : reference/concepts.xml
:
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
<xsl:param>boost.root=../../../..
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : concepts ;
explicit boostrelease ;

View File

@@ -0,0 +1,59 @@
<?xml version="1.0"?>
<concept name="Assignable" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="X" role="assignable-type"/>
<models-sentence>The type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>Assignable types must have copy constructors,
<code>operator=</code> for assignment, and the <code>swap()</code>
function defined.</para>
</description>
<notation variables="x y">
<sample-value>
<type name="X"/>
</sample-value>
</notation>
<refines const="no" concept="CopyConstructible"/>
<valid-expression name="Assignment">
<assign>
<sample-value><reference-to><type name="X"/></reference-to></sample-value>
<sample-value><const><reference-to><type name="X"/></reference-to></const></sample-value>
</assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="X"/></reference-to>
</require-same-type>
</return-type>
<semantics>Require <code>operator=</code></semantics>
</valid-expression>
<valid-expression name="Swap">
<apply-function name="swap">
<sample-value><reference-to><type name="X"/></reference-to></sample-value>
<sample-value><reference-to><type name="X"/></reference-to></sample-value>
</apply-function>
<return-type><require-same-type><type name="void"/></require-same-type></return-type>
<semantics>Require <code>swap()</code> function</semantics>
</valid-expression>
<example-model>
<type name="int"/>
</example-model>
</concept>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0"?>
<concept name="BidirectionalIterator" category="Iterator"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="Iter" role="iterator-type"/>
<use-header name="iterator"/>
<models-sentence>The iterator type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>A bidirectional iterator is an iterator that can read through a sequence
of values. It can move in either direction through the sequence, and can
be either mutable (data pointed to by it can be changed) or not mutable.</para>
<para>An iterator represents a position in a sequence. Therefore, the
iterator can point into the sequence (returning a value when dereferenced
and being incrementable), or be off-the-end (and not dereferenceable or
incrementable).</para>
</description>
<associated-type name="value_type">
<get-member-type name="value_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The value type of the iterator</simpara></description>
</associated-type>
<refines const="no" concept="ForwardIterator"/>
<notation variables="i j">
<sample-value>
<type name="Iter"/>
</sample-value>
</notation>
<associated-type name="category">
<get-member-type name="iterator_category">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The category of the iterator</simpara></description>
</associated-type>
<notation variables="x">
<sample-value>
<type name="value_type"/>
</sample-value>
</notation>
<valid-type-expression name="Category tag">
<description/>
<type name="category"/>
<return-type>
<derived-from testable="yes">
<type name="std::bidirectional_iterator_tag"/>
</derived-from>
</return-type>
</valid-type-expression>
<valid-expression name="Predecrement">
<predecrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</predecrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end) and some dereferenceable iterator <code>j</code> exists
such that <code>i == ++j</code></precondition>
</valid-expression>
<valid-expression name="Postdecrement">
<postdecrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postdecrement>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<precondition>Same as for predecrement</precondition>
<semantics>Equivalent to <code>{Iter j = i; --i; return j;}</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<complexity>
All iterator operations must take amortized constant time.
</complexity>
<invariant name="Predecrement must return object">
<code>&amp;i = &amp;(--i)</code>
</invariant>
<invariant name="Unique path through sequence">
<code>i == j</code> implies <code>--i == --j</code>
</invariant>
<invariant name="Increment and decrement are inverses">
<code>++i; --i;</code> and <code>--i; ++i;</code> must end up with the
value of <code>i</code> unmodified, if <code>i</code> both of the
operations in the pair are valid.
</invariant>
<example-model>
<pointer-to>
<type name="T"/>
</pointer-to>
</example-model>
<example-model>
<get-member-type name="iterator">
<apply-template name="std::list">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
<see-also concept="RandomAccessIterator"/>
</concept>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0"?>
<concept name="CopyConstructible" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="X" role="copy-constructible-type"/>
<models-sentence>The type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>Copy constructible types must be able to be constructed from another
member of the type.</para>
</description>
<notation variables="x y">
<sample-value>
<type name="X"/>
</sample-value>
</notation>
<valid-expression name="Copy construction">
<construct template-parameters="">
<type name="X"/>
<sample-value><const><reference-to><type name="X"/></reference-to></const></sample-value>
</construct>
<return-type>
<require-same-type testable="yes">
<type name="X"/>
</require-same-type>
</return-type>
<semantics>Require copy constructor.</semantics>
</valid-expression>
<example-model>
<type name="int"/>
</example-model>
</concept>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0"?>
<concept name="DefaultConstructible" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="X" role="default-constructible-type"/>
<models-sentence>The type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description><para>DefaultConstructible objects only need to have a default
constructor.</para></description>
<valid-expression name="Construction">
<construct template-parameters="">
<type name="X"/>
</construct>
<return-type><require-same-type testable="yes"><type name="X"/></require-same-type></return-type>
<semantics>Construct an instance of the type with default parameters.</semantics>
</valid-expression>
<example-model>
<type name="int"/>
</example-model>
<example-model>
<apply-template name="std::vector">
<type name="double"/>
</apply-template>
</example-model>
</concept>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0"?>
<concept name="EqualityComparable" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="X" role="comparable-type"/>
<models-sentence>The type <arg num="1"/> must be a model of
<self/>.</models-sentence>
<description><para>Equality Comparable types must have <code>==</code> and
<code>!=</code> operators.</para></description>
<notation variables="x y">
<sample-value>
<type name="X"/>
</sample-value>
</notation>
<valid-expression name="Equality test">
<equal-to>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</equal-to>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Inequality test">
<not-equal-to>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</not-equal-to>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<example-model>
<type name="int"/>
</example-model>
<example-model>
<apply-template name="std::vector">
<type name="int"/>
</apply-template>
</example-model>
</concept>

View File

@@ -0,0 +1,174 @@
<?xml version="1.0"?>
<concept name="ForwardIterator" category="Iterator"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="Iter" role="iterator-type"/>
<use-header name="iterator"/>
<models-sentence>The iterator type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>A forward iterator is an iterator that can read through a sequence of
values. It is multi-pass (old values of the iterator can be
re-used), and can be either mutable (data pointed to by it can be
changed) or not mutable.</para>
<para>An iterator represents a position in a sequence. Therefore, the
iterator can point into the sequence (returning a value when dereferenced
and being incrementable), or be off-the-end (and not dereferenceable or
incrementable).</para>
</description>
<associated-type name="value_type">
<get-member-type name="value_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The value type of the iterator</simpara></description>
</associated-type>
<refines const="no" concept="InputIterator"/>
<refines const="no" concept="OutputIterator"/>
<!-- DPG doesn't understand this
<models const="no" testable="yes" concept="Input Iterator">
<type name="Iter"/>
</models>
-->
<!--
<models-when-mutable concept="Output Iterator">
<type name="Iter"/>
<type name="value_type"/>
</models-when-mutable>
-->
<notation variables="i j">
<sample-value>
<type name="Iter"/>
</sample-value>
</notation>
<associated-type name="category">
<get-member-type name="iterator_category">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The category of the iterator</simpara></description>
</associated-type>
<notation variables="x">
<sample-value>
<type name="value_type"/>
</sample-value>
</notation>
<valid-type-expression name="Category tag">
<description/>
<type name="category"/>
<return-type>
<derived-from testable="yes">
<type name="std::forward_iterator_tag"/>
</derived-from>
</return-type>
</valid-type-expression>
<valid-expression name="Dereference">
<dereference>
<sample-value><type name="Iter"/></sample-value>
</dereference>
<return-type>
<require-same-type testable="yes">
<const-if-not-mutable>
<reference-to><type name="value_type"/></reference-to>
</const-if-not-mutable>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Member access">
<pointer-member>
<sample-value><type name="Iter"/></sample-value>
</pointer-member>
<return-type>
<require-same-type testable="yes">
<const-if-not-mutable>
<pointer-to><type name="value_type"/></pointer-to>
</const-if-not-mutable>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Preincrement">
<preincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</preincrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Postincrement">
<postincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postincrement>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<semantics>Equivalent to <code>{Iter j = i; ++i; return j;}</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<complexity>
All iterator operations must take amortized constant time.
</complexity>
<invariant name="Predecrement must return object">
<code>&amp;i = &amp;(++i)</code>
</invariant>
<invariant name="Unique path through sequence">
<code>i == j</code> implies <code>++i == ++j</code>
</invariant>
<example-model>
<pointer-to>
<type name="T"/>
</pointer-to>
</example-model>
<example-model>
<get-member-type name="iterator">
<apply-template name="std::hash_set">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
<see-also concept="BidirectionalIterator"/>
</concept>

View File

@@ -0,0 +1,168 @@
<?xml version="1.0"?>
<concept name="InputIterator" category="Iterator"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="Iter" role="iterator-type"/>
<use-header name="iterator"/>
<models-sentence>The iterator type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>An input iterator is an iterator that can read through a sequence of
values. It is single-pass (old values of the iterator cannot be
re-used), and read-only.</para>
<para>An input iterator represents a position in a sequence. Therefore, the
iterator can point into the sequence (returning a value when dereferenced
and being incrementable), or be off-the-end (and not dereferenceable or
incrementable).</para>
</description>
<refines const="no" concept="Assignable"/>
<refines const="no" concept="DefaultConstructible"/>
<refines const="no" concept="EqualityComparable"/>
<notation variables="i j">
<sample-value>
<type name="Iter"/>
</sample-value>
</notation>
<associated-type name="value_type">
<get-member-type name="value_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The value type of the iterator (not necessarily what
<code>*i</code> returns)</simpara></description>
</associated-type>
<associated-type name="difference_type">
<get-member-type name="difference_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The difference type of the iterator</simpara></description>
</associated-type>
<associated-type name="category">
<get-member-type name="iterator_category">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The category of the iterator</simpara></description>
</associated-type>
<notation variables="x">
<sample-value>
<type name="value_type"/>
</sample-value>
</notation>
<valid-type-expression name="Category tag">
<description/>
<type name="category"/>
<return-type>
<derived-from testable="yes">
<type name="std::input_iterator_tag"/>
</derived-from>
<models-as-first-arg const="no" testable="yes" concept="DefaultConstructible"/>
<models-as-first-arg const="no" testable="yes" concept="CopyConstructible"/>
</return-type>
</valid-type-expression>
<valid-type-expression name="Value type copy constructibility">
<description/>
<type name="value_type"/>
<return-type>
<models-as-first-arg const="no" testable="yes" concept="CopyConstructible"/>
</return-type>
</valid-type-expression>
<valid-type-expression name="Difference type properties">
<description/>
<type name="difference_type"/>
<return-type>
<models-as-first-arg const="no" testable="yes" concept="SignedInteger"/>
</return-type>
</valid-type-expression>
<valid-expression name="Dereference">
<dereference>
<sample-value><type name="Iter"/></sample-value>
</dereference>
<return-type>
<convertible-to testable="yes"><type name="value_type"/></convertible-to>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Preincrement">
<preincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</preincrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Postincrement">
<postincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postincrement>
<return-type/>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<semantics>Equivalent to <code>(void)(++i)</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<valid-expression name="Postincrement and dereference">
<dereference>
<postincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postincrement>
</dereference>
<return-type>
<convertible-to testable="yes"><type name="value_type"/></convertible-to>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<semantics>Equivalent to <code>{value_type t = *i; ++i; return t;}</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<complexity>
All iterator operations must take amortized constant time.
</complexity>
<example-model>
<type name="std::istream_iterator"/>
</example-model>
<see-also concept="OutputIterator"/>
<see-also concept="ForwardIterator"/>
</concept>

View File

@@ -0,0 +1,81 @@
<?xml version="1.0"?>
<concept name="LessThanComparable" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="X" role="comparable-type"/>
<models-sentence>The type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description><para>LessThanComparable types must have <code>&lt;</code>,
<code>&gt;</code>, <code>&lt;=</code>, and <code>&gt;=</code>
operators.</para></description>
<notation variables="x y"><sample-value><type name="X"/></sample-value></notation>
<valid-expression name="Less than">
<less-than>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</less-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
<semantics>Determine if one value is less than another.</semantics>
</valid-expression>
<valid-expression name="Less than or equal">
<less-than-or-equal>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</less-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
<semantics>Determine if one value is less than or equal to another.</semantics>
</valid-expression>
<valid-expression name="Greater than">
<greater-than>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</greater-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
<semantics>Determine if one value is greater than another.</semantics>
</valid-expression>
<valid-expression name="Greater than or equal to">
<greater-than-or-equal>
<sample-value><type name="X"/></sample-value>
<sample-value><type name="X"/></sample-value>
</greater-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
<semantics>Determine if one value is greater than or equal to another.</semantics>
</valid-expression>
<example-model>
<type name="int"/>
</example-model>
</concept>

View File

@@ -0,0 +1,203 @@
<?xml version="1.0"?>
<concept name="OutputIterator" category="Iterator"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="Iter" role="iterator-type"/>
<param name="ValueType" role="value-type"/>
<use-header name="iterator"/>
<models-sentence>The iterator type <arg num="1"/> (with value type <arg num="2"/>) must be a model of <self/>.</models-sentence>
<description>
<para>An output iterator is an iterator that can write a sequence of
values. It is single-pass (old values of the iterator cannot be
re-used), and write-only.</para>
<para>An output iterator represents a position in a (possibly infinite)
sequence. Therefore, the iterator can point into the sequence (returning
a value when dereferenced and being incrementable), or be off-the-end
(and not dereferenceable or incrementable).</para>
</description>
<models const="no" testable="yes" concept="Assignable">
<type name="Iter"/>
</models>
<models const="no" testable="yes" concept="Assignable">
<type name="ValueType"/>
</models>
<models const="no" testable="yes" concept="DefaultConstructible">
<type name="Iter"/>
</models>
<models const="no" testable="yes" concept="EqualityComparable">
<type name="Iter"/>
</models>
<associated-type name="value_type">
<get-member-type name="value_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The stated value type of the iterator (should be
<code>void</code> for an output iterator that does not model some other
iterator concept).</simpara></description>
</associated-type>
<associated-type name="difference_type">
<get-member-type name="difference_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The difference type of the iterator</simpara></description>
</associated-type>
<associated-type name="category">
<get-member-type name="iterator_category">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The category of the iterator</simpara></description>
</associated-type>
<notation variables="i j">
<sample-value>
<type name="Iter"/>
</sample-value>
</notation>
<notation variables="x">
<sample-value>
<type name="ValueType"/>
</sample-value>
</notation>
<valid-type-expression name="Category tag">
<description/>
<type name="category"/>
<return-type>
<derived-from testable="yes">
<type name="std::output_iterator_tag"/>
</derived-from>
<models-as-first-arg const="no" testable="yes" concept="DefaultConstructible"/>
<models-as-first-arg const="no" testable="yes" concept="CopyConstructible"/>
</return-type>
</valid-type-expression>
<valid-type-expression name="Difference type properties">
<description/>
<type name="difference_type"/>
<return-type>
<models-as-first-arg const="no" testable="yes" concept="SignedInteger"/>
</return-type>
</valid-type-expression>
<valid-expression name="Dereference">
<dereference>
<sample-value><type name="Iter"/></sample-value>
</dereference>
<return-type/>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Dereference and assign">
<assign>
<dereference>
<sample-value><type name="Iter"/></sample-value>
</dereference>
<sample-value><const><reference-to><type name="ValueType"/></reference-to></const></sample-value>
</assign>
<return-type/>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<postcondition><code>*i</code> may not be written to again until it has
been incremented.</postcondition>
</valid-expression>
<valid-expression name="Preincrement">
<preincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</preincrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
</valid-expression>
<valid-expression name="Postincrement">
<postincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postincrement>
<return-type/>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<semantics>Equivalent to <code>(void)(++i)</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<valid-expression name="Postincrement, dereference, and assign">
<assign>
<dereference>
<postincrement>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
</postincrement>
</dereference>
<sample-value><const><reference-to><type name="ValueType"/></reference-to></const></sample-value>
</assign>
<return-type/>
<precondition><code>i</code> is incrementable (not
off-the-end)</precondition>
<semantics>Equivalent to <code>{*i = t; ++i;}</code></semantics>
<postcondition><code>i</code> is dereferenceable or
off-the-end</postcondition>
</valid-expression>
<complexity>
All iterator operations must take amortized constant time.
</complexity>
<example-model>
<type name="std::ostream_iterator"/>
<type name="..."/>
</example-model>
<example-model>
<type name="std::insert_iterator"/>
<type name="..."/>
</example-model>
<example-model>
<type name="std::front_insert_iterator"/>
<type name="..."/>
</example-model>
<example-model>
<type name="std::back_insert_iterator"/>
<type name="..."/>
</example-model>
<see-also concept="InputIterator"/>
<see-also concept="ForwardIterator"/>
</concept>

View File

@@ -0,0 +1,313 @@
<?xml version="1.0"?>
<concept name="RandomAccessIterator" category="Iterator"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="Iter" role="iterator-type"/>
<use-header name="iterator"/>
<models-sentence>The iterator type <arg num="1"/> must be a model of <self/>.</models-sentence>
<description>
<para>A random access iterator is an iterator that can read through
a sequence of values. It can move in either direction through the
sequence (by any amount in constant time), and can be either mutable
(data pointed to by it can be changed) or not mutable.</para>
<para>An iterator represents a position in a sequence. Therefore,
the iterator can point into the sequence (returning a value when
dereferenced and being incrementable), or be off-the-end (and not
dereferenceable or incrementable).</para>
</description>
<associated-type name="value_type">
<get-member-type name="value_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The value type of the iterator</simpara></description>
</associated-type>
<refines const="no" concept="BidirectionalIterator"/>
<refines const="no" concept="LessThanComparable"/>
<notation variables="i j">
<sample-value>
<type name="Iter"/>
</sample-value>
</notation>
<associated-type name="category">
<get-member-type name="iterator_category">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The category of the iterator</simpara></description>
</associated-type>
<associated-type name="difference_type">
<get-member-type name="difference_type">
<apply-template name="std::iterator_traits">
<type name="Iter"/>
</apply-template>
</get-member-type>
<description><simpara>The difference type of the iterator (measure of the number
of steps between two iterators)</simpara></description>
</associated-type>
<notation variables="x">
<sample-value>
<type name="value_type"/>
</sample-value>
</notation>
<notation variables="n">
<sample-value>
<type name="difference_type"/>
</sample-value>
</notation>
<notation variables="int_off">
<sample-value>
<type name="int"/>
</sample-value>
</notation>
<valid-type-expression name="Category tag">
<description/>
<type name="category"/>
<return-type>
<derived-from testable="yes">
<type name="std::random_access_iterator_tag"/>
</derived-from>
</return-type>
</valid-type-expression>
<valid-expression name="Motion">
<add-assign>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
<sample-value><type name="difference_type"/></sample-value>
</add-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<semantics>Equivalent to applying <code>i++</code> <code>n</code> times
if <code>n</code> is positive, applying <code>i--</code>
<code>-n</code> times if <code>n</code> is negative, and to a null
operation if <code>n</code> is zero.</semantics>
</valid-expression>
<valid-expression name="Motion (with integer offset)">
<add-assign>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
<sample-value><type name="int"/></sample-value>
</add-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<semantics>Equivalent to applying <code>i++</code> <code>n</code> times
if <code>n</code> is positive, applying <code>i--</code>
<code>-n</code> times if <code>n</code> is negative, and to a null
operation if <code>n</code> is zero.</semantics>
</valid-expression>
<valid-expression name="Subtractive motion">
<subtract-assign>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
<sample-value><type name="difference_type"/></sample-value>
</subtract-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<semantics>Equivalent to <code>i+=(-n)</code></semantics>
</valid-expression>
<valid-expression name="Subtractive motion (with integer offset)">
<subtract-assign>
<sample-value><reference-to><type name="Iter"/></reference-to></sample-value>
<sample-value><type name="int"/></sample-value>
</subtract-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="Iter"/></reference-to>
</require-same-type>
</return-type>
<semantics>Equivalent to <code>i+=(-n)</code></semantics>
</valid-expression>
<valid-expression name="Addition">
<add>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="difference_type"/></sample-value>
</add>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>{Iter j = i; j += n; return j;}</code></semantics>
</valid-expression>
<valid-expression name="Addition with integer">
<add>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="int"/></sample-value>
</add>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>{Iter j = i; j += n; return j;}</code></semantics>
</valid-expression>
<valid-expression name="Addition (count first)">
<add>
<sample-value><type name="difference_type"/></sample-value>
<sample-value><type name="Iter"/></sample-value>
</add>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>i + n</code></semantics>
</valid-expression>
<valid-expression name="Addition with integer (count first)">
<add>
<sample-value><type name="int"/></sample-value>
<sample-value><type name="Iter"/></sample-value>
</add>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>i + n</code></semantics>
</valid-expression>
<valid-expression name="Subtraction">
<subtract>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="difference_type"/></sample-value>
</subtract>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>i + (-n)</code></semantics>
</valid-expression>
<valid-expression name="Subtraction with integer">
<subtract>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="int"/></sample-value>
</subtract>
<return-type>
<require-same-type testable="yes"><type name="Iter"/></require-same-type>
</return-type>
<semantics>Equivalent to <code>i + (-n)</code></semantics>
</valid-expression>
<valid-expression name="Distance">
<subtract>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="Iter"/></sample-value>
</subtract>
<return-type>
<require-same-type testable="yes"><type name="difference_type"/></require-same-type>
</return-type>
<semantics>The number of times <code>i</code> must be incremented (or
decremented if the result is negative) to reach <code>j</code>. Not
defined if <code>j</code> is not reachable from
<code>i</code>.</semantics>
</valid-expression>
<valid-expression name="Element access">
<subscript>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="difference_type"/></sample-value>
</subscript>
<return-type>
<require-same-type testable="yes">
<const-if-not-mutable>
<reference-to>
<type name="value_type"/>
</reference-to>
</const-if-not-mutable>
</require-same-type>
</return-type>
<semantics>Equivalent to <code>*(i + n)</code></semantics>
</valid-expression>
<valid-expression name="Element access with integer index">
<subscript>
<sample-value><type name="Iter"/></sample-value>
<sample-value><type name="int"/></sample-value>
</subscript>
<return-type>
<require-same-type testable="yes">
<const-if-not-mutable>
<reference-to>
<type name="value_type"/>
</reference-to>
</const-if-not-mutable>
</require-same-type>
</return-type>
<semantics>Equivalent to <code>*(i + n)</code></semantics>
</valid-expression>
<complexity>
All iterator operations must take amortized constant time.
</complexity>
<example-model>
<pointer-to>
<type name="T"/>
</pointer-to>
</example-model>
<example-model>
<get-member-type name="iterator">
<apply-template name="std::vector">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
<example-model>
<get-member-type name="const_iterator">
<apply-template name="std::vector">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
<example-model>
<get-member-type name="iterator">
<apply-template name="std::deque">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
<example-model>
<get-member-type name="const_iterator">
<apply-template name="std::deque">
<type name="T"/>
</apply-template>
</get-member-type>
</example-model>
</concept>

View File

@@ -0,0 +1,549 @@
<?xml version="1.0"?>
<concept name="SignedInteger" category="Utility"><!--
Based on concepts from the SGI Standard Template Library documentation:
Copyright (c) 1996-1999
Silicon Graphics Computer Systems, Inc.
Copyright (c) 1994
Hewlett-Packard Company
--><!--
Copyright 2000-2001 University of Notre Dame du Lac.
Copyright 2001-2002 Indiana University.
Some concepts based on versions from the MTL draft manual and Boost Graph
and Property Map documentation:
Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
-->
<param name="T" role="integral-type"/>
<models-sentence>Integer type <arg num="1"/> must be a model of <self/>.</models-sentence>
<refines const="no" concept="CopyConstructible"/>
<refines const="no" concept="Assignable"/>
<refines const="no" concept="DefaultConstructible"/>
<refines const="no" concept="EqualityComparable"/>
<refines const="no" concept="LessThanComparable"/>
<notation variables="x y z">
<sample-value><type name="T"/></sample-value>
</notation>
<notation variables="a b">
<sample-value><type name="int"/></sample-value>
</notation>
<!--
<valid-type-expression name="int-ness">
<documentation>Should this really be required?</documentation>
<type name="T"/>
<return-type>
<require-same-type>
<type name="int"/>
</require-same-type>
</return-type>
</valid-type-expression>
-->
<valid-expression name="Conversion from int">
<construct template-parameters="">
<type name="T"/>
<sample-value><type name="int"/></sample-value>
</construct>
<return-type><require-same-type testable="yes">
<type name="T"/>
</require-same-type></return-type>
</valid-expression>
<valid-expression name="Preincrement">
<preincrement>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
</preincrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Predecrement">
<predecrement>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
</predecrement>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Postincrement">
<postincrement>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
</postincrement>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Postdecrement">
<postdecrement>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
</postdecrement>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Sum">
<add>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</add>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Sum with int">
<add>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</add>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Sum-assignment">
<add-assign>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</add-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Sum-assignment with int">
<add-assign>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</add-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Difference">
<subtract>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</subtract>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Difference with int">
<subtract>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</subtract>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Product">
<multiply>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</multiply>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Product with int">
<multiply>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</multiply>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Product-assignment with int">
<multiply-assign>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</multiply-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Product with int on left">
<multiply>
<sample-value>
<type name="int"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</multiply>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Quotient">
<divide>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</divide>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Quotient with int">
<divide>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</divide>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Right-shift">
<shift-right>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</shift-right>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Right-shift with int">
<shift-right>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</shift-right>
<return-type>
<require-same-type testable="yes">
<type name="T"/>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Right-shift-assignment with int">
<shift-right-assign>
<sample-value>
<reference-to><type name="T"/></reference-to>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</shift-right-assign>
<return-type>
<require-same-type testable="yes">
<reference-to><type name="T"/></reference-to>
</require-same-type>
</return-type>
</valid-expression>
<valid-expression name="Less-than comparison">
<less-than>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</less-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Less-than comparison with int">
<less-than>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</less-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Less-than comparison with size_t">
<less-than>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="std::size_t"/>
</sample-value>
</less-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Greater-than comparison">
<greater-than>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</greater-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Greater-than comparison with int">
<greater-than>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</greater-than>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Less-than-or-equal comparison">
<less-than-or-equal>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</less-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Less-than-or-equal comparison with int">
<less-than-or-equal>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</less-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Greater-than-or-equal comparison">
<greater-than-or-equal>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</greater-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Greater-than-or-equal comparison with int">
<greater-than-or-equal>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</greater-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Greater-than-or-equal comparison with int on left">
<greater-than-or-equal>
<sample-value>
<type name="int"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</greater-than-or-equal>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Equality comparison">
<equal-to>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="T"/>
</sample-value>
</equal-to>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-expression name="Equality comparison with int">
<equal-to>
<sample-value>
<type name="T"/>
</sample-value>
<sample-value>
<type name="int"/>
</sample-value>
</equal-to>
<return-type>
<convertible-to testable="yes">
<type name="bool"/>
</convertible-to>
</return-type>
</valid-expression>
<valid-type-expression name="Conversion to int">
<documentation/>
<type name="T"/>
<return-type>
<convertible-to testable="yes">
<type name="int"/>
</convertible-to>
</return-type>
</valid-type-expression>
</concept>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE library-reference PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library-reference id="concepts.reference"
xmlns:xi="http://www.w3.org/2001/XInclude"
last-revision="$Date$">
<sectioninfo>
<copyright>
<year>2001</year>
<year>2002</year>
<holder>Indiana University</holder>
</copyright>
<copyright>
<year>2000</year>
<year>2001</year>
<holder>University of Notre Dame du Lac</holder>
</copyright>
<copyright>
<year>2000</year>
<holder>Jeremy Siek</holder>
<holder>Lie-Quan Lee</holder>
<holder>Andrew Lumsdaine</holder>
</copyright>
<copyright>
<year>1996</year>
<year>1997</year>
<year>1998</year>
<year>1999</year>
<holder>Silicon Graphics Computer Systems, Inc.</holder>
</copyright>
<copyright>
<year>1994</year>
<holder>Hewlett-Packard Company</holder>
</copyright>
<legalnotice>
<para>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at
<ulink
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
</para>
<para>This product includes software developed at the University
of Notre Dame and the Pervasive Technology Labs at Indiana
University. For technical information contact Andrew Lumsdaine
at the Pervasive Technology Labs at Indiana University. For
administrative and license questions contact the Advanced
Research and Technology Institute at 351 West 10th Street.
Indianapolis, Indiana 46202, phone 317-278-4100, fax
317-274-5902.</para>
<para>Some concepts based on versions from the MTL draft manual
and Boost Graph and Property Map documentation, the SGI Standard
Template Library documentation and the Hewlett-Packard STL,
under the following license:
<blockquote><simpara>Permission to use, copy, modify, distribute and
sell this software and its documentation for any purpose is
hereby granted without fee, provided that the above copyright
notice appears in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation. Silicon Graphics makes no representations
about the suitability of this software for any purpose. It is
provided "as is" without express or implied
warranty.</simpara></blockquote></para>
</legalnotice>
</sectioninfo>
<title>Concept reference</title>
<xi:include href="Assignable.xml"/>
<xi:include href="InputIterator.xml"/>
<xi:include href="OutputIterator.xml"/>
<xi:include href="ForwardIterator.xml"/>
<xi:include href="BidirectionalIterator.xml"/>
<xi:include href="RandomAccessIterator.xml"/>
<xi:include href="DefaultConstructible.xml"/>
<xi:include href="CopyConstructible.xml"/>
<xi:include href="EqualityComparable.xml"/>
<xi:include href="LessThanComparable.xml"/>
<xi:include href="SignedInteger.xml"/>
</library-reference>

View File

@@ -0,0 +1,205 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000, David Abrahams 2007 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="../../rst.css" type="text/css" />
<title>Concept Checking Implementation</title>
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="warning" id="warning"><font color=
"red">Warning</font></a></h2>
<p><font color="red">This documentation is out-of-date; similar but
newer implementation techniques are now used. This documentation
also refers to components and protocols in the library's old
interface such as <code>BOOST_CLASS_REQUIRES</code>
and <code>constraints()</code> functions, which are still supported
but deprecated.</font></p>
<h2><a name="implementation" id="implementation">Implementation</a></h2>
<p>Ideally we would like to catch, and indicate, the concept violation at
the point of instantiation. As mentioned in D&amp;E[<a href=
"bibliography.htm#stroustrup94:_design_evolution">2</a>], the error can be
caught by exercising all of the requirements needed by the function
template. Exactly how the requirements (the valid expressions in
particular) are exercised is a tricky issue, since we want the code to be
compiled—<i>but not executed</i>. Our approach is to exercise the
requirements in a separate function that is assigned to a function pointer.
In this case, the compiler will instantiate the function but will not
actually invoke it. In addition, an optimizing compiler will remove the
pointer assignment as ``dead code'' (though the run-time overhead added by
the assignment would be trivial in any case). It might be conceivable for a
compiler to skip the semantic analysis and compilation of the constraints
function in the first place, which would make our function pointer
technique ineffective. However, this is unlikely because removal of
unnecessary code and functions is typically done in later stages of a
compiler. We have successfully used the function pointer technique with GNU
C++, Microsoft Visual C++, and several EDG-based compilers (KAI C++, SGI
MIPSpro). The following code shows how this technique can be applied to the
<tt>std::stable_sort()</tt> function:</p>
<pre>
template &lt;class RandomAccessIterator&gt;
void stable_sort_constraints(RandomAccessIterator i)
{
typename std::iterator_traits&lt;RandomAccessIterator&gt;
::difference_type n;
i += n; // exercise the requirements for RandomAccessIterator
...
}
template &lt;class RandomAccessIterator&gt;
void stable_sort(RandomAccessIterator first, RandomAccessIterator last)
{
typedef void (*fptr_type)(RandomAccessIterator);
fptr_type x = &amp;stable_sort_constraints;
...
}
</pre>
<p>There is often a large set of requirements that need to be checked, and
it would be cumbersome for the library implementor to write constraint
functions like <tt>stable_sort_constraints()</tt> for every public
function. Instead, we group sets of valid expressions together, according
to the definitions of the corresponding concepts. For each concept we
define a concept checking class template where the template parameter is
for the type to be checked. The class contains a <tt>constraints()</tt>
member function which exercises all of the valid expressions of the
concept. The objects used in the constraints function, such as <tt>n</tt>
and <tt>i</tt>, are declared as data members of the concept checking
class.</p>
<pre>
template &lt;class Iter&gt;
struct RandomAccessIteratorConcept
{
void constraints()
{
i += n;
...
}
typename std::iterator_traits&lt;RandomAccessIterator&gt;
::difference_type n;
Iter i;
...
};
</pre>
<p>We can still use the function pointer mechanism to cause instantiation
of the constraints function, however now it will be a member function
pointer. To make it easy for the library implementor to invoke the concept
checks, we wrap the member function pointer mechanism in a function named
<tt>function_requires()</tt>. The following code snippet shows how to use
<tt>function_requires()</tt> to make sure that the iterator is a <a href=
"http://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>.</p>
<pre>
template &lt;class Iter&gt;
void stable_sort(Iter first, Iter last)
{
function_requires&lt; RandomAccessIteratorConcept&lt;Iter&gt; &gt;();
...
}
</pre>
<p>The definition of the <tt>function_requires()</tt> is as follows. The
<tt>Concept</tt> is the concept checking class that has been instantiated
with the modeling type. We assign the address of the constraints member
function to the function pointer <tt>x</tt>, which causes the instantiation
of the constraints function and checking of the concept's valid
expressions. We then assign <tt>x</tt> to <tt>x</tt> to avoid unused
variable compiler warnings, and wrap everything in a do-while loop to
prevent name collisions.</p>
<pre>
template &lt;class Concept&gt;
void function_requires()
{
void (Concept::*x)() = BOOST_FPTR Concept::constraints;
ignore_unused_variable_warning(x);
}
</pre>
<p>To check the type parameters of class templates, we provide the
<tt>BOOST_CLASS_REQUIRE</tt> macro which can be used inside the body of a
class definition (whereas <tt>function_requires()</tt> can only be used
inside of a function body). This macro declares a nested class template,
where the template parameter is a function pointer. We then use the nested
class type in a typedef with the function pointer type of the constraint
function as the template argument. We use the <tt>type_var</tt> and
<tt>concept</tt> names in the nested class and typedef names to help
prevent name collisions.</p>
<pre>
#define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
typedef void (ns::concept &lt;type_var&gt;::* func##type_var##concept)(); \
template &lt;func##type_var##concept _Tp1&gt; \
struct concept_checking_##type_var##concept { }; \
typedef concept_checking_##type_var##concept&lt; \
BOOST_FPTR ns::concept&lt;type_var&gt;::constraints&gt; \
concept_checking_typedef_##type_var##concept
</pre>
<p>In addition, there are versions of <tt>BOOST_CLASS_REQUIRE</tt> that
take more arguments, to handle concepts that include interactions between
two or more types. <tt>BOOST_CLASS_REQUIRE</tt> was not used in the
implementation of the BCCL concept checks because some compilers do not
implement template parameters of function pointer type.
<!-- We decided not to go with this version since it is easier to misuse
To check the type parameters of class templates, we provide the
<tt>class_requires</tt> class which can be used inside the body of a
class definition (whereas <tt>function_requires()</tt> can only be
used inside of a function body). <tt>class_requires</tt> declares a
nested class template, where the template parameter is a function
pointer. We then use the nested class type in a typedef with the
function pointer type of the constraint function as the template
argument.
<pre>
template &lt;class Concept&gt;
class class_requires
{
typedef void (Concept::* function_pointer)();
template &lt;function_pointer Fptr&gt;
struct dummy_struct { };
public:
typedef dummy_struct&lt; BOOST_FPTR Concept::constraints &gt; check;
};
</pre>
<tt>class_requires</tt> was not used in the implementation of the
Boost Concept Checking Library concept checks because several
compilers do not implement template parameters of function pointer
type.
--></p>
<p><a href="./reference.htm">Next: Reference</a><br />
<a href="prog_with_concepts.htm">Prev: Programming With
Concepts</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,45 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP
# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP
# include <boost/config.hpp>
# include <boost/config/workaround.hpp>
// The old protocol used a constraints() member function in concept
// checking classes. If the compiler supports SFINAE, we can detect
// that function and seamlessly support the old concept checking
// classes. In this release, backward compatibility with the old
// concept checking classes is enabled by default, where available.
// The old protocol is deprecated, though, and backward compatibility
// will no longer be the default in the next release.
# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \
&& !defined(BOOST_NO_SFINAE) \
\
&& !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4))
// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to
// check for the presence of particularmember functions.
# define BOOST_OLD_CONCEPT_SUPPORT
# endif
# ifdef BOOST_MSVC
# include <boost/concept/detail/msvc.hpp>
# elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
# include <boost/concept/detail/borland.hpp>
# else
# include <boost/concept/detail/general.hpp>
# endif
// Usage, in class or function context:
//
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
//
# define BOOST_CONCEPT_ASSERT(ModelInParens) \
BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens)
#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP

View File

@@ -0,0 +1,16 @@
// Copyright David Abrahams 2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP
namespace boost
{
namespace concepts {}
# if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD)
namespace concept = concepts;
# endif
} // namespace boost::concept
#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP

View File

@@ -0,0 +1,30 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP
# include <boost/preprocessor/cat.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
namespace boost { namespace concepts {
template <class ModelFnPtr>
struct require;
template <class Model>
struct require<void(*)(Model)>
{
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
};
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
enum \
{ \
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
boost::concepts::require<ModelFnPtr>::instantiate \
}
}} // namespace boost::concept
#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP

View File

@@ -0,0 +1,34 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
# include <boost/preprocessor/seq/for_each_i.hpp>
# include <boost/preprocessor/seq/enum.hpp>
# include <boost/preprocessor/comma_if.hpp>
# include <boost/preprocessor/cat.hpp>
#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP
// BOOST_concept(SomeName, (p1)(p2)...(pN))
//
// Expands to "template <class p1, class p2, ...class pN> struct SomeName"
//
// Also defines an equivalent SomeNameConcept for backward compatibility.
// Maybe in the next release we can kill off the "Concept" suffix for good.
# define BOOST_concept(name, params) \
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
struct name; /* forward declaration */ \
\
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
struct BOOST_PP_CAT(name,Concept) \
: name< BOOST_PP_SEQ_ENUM(params) > \
{ \
}; \
\
template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \
struct name
// Helper for BOOST_concept, above.
# define BOOST_CONCEPT_typename(r, ignored, index, t) \
BOOST_PP_COMMA_IF(index) typename t

View File

@@ -0,0 +1,5 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# undef BOOST_concept_typename
# undef BOOST_concept

View File

@@ -0,0 +1,98 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP
# include <boost/config.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept/detail/has_constraints.hpp>
# include <boost/type_traits/conditional.hpp>
# endif
// This implementation works on Comeau and GCC, all the way back to
// 2.95
namespace boost { namespace concepts {
template <class ModelFn>
struct requirement_;
namespace detail
{
template <void(*)()> struct instantiate {};
}
template <class Model>
struct requirement
{
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnonnull"
# endif
static void failed() { ((Model*)0)->~Model(); }
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic pop
# endif
};
struct failed {};
template <class Model>
struct requirement<failed ************ Model::************>
{
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnonnull"
# endif
static void failed() { ((Model*)0)->~Model(); }
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic pop
# endif
};
# ifdef BOOST_OLD_CONCEPT_SUPPORT
template <class Model>
struct constraint
{
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnonnull"
# endif
static void failed() { ((Model*)0)->constraints(); }
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic pop
# endif
};
template <class Model>
struct requirement_<void(*)(Model)>
: boost::conditional<
concepts::not_satisfied<Model>::value
, constraint<Model>
, requirement<failed ************ Model::************>
>::type
{};
# else
// For GCC-2.x, these can't have exactly the same name
template <class Model>
struct requirement_<void(*)(Model)>
: requirement<failed ************ Model::************>
{};
# endif
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
typedef ::boost::concepts::detail::instantiate< \
&::boost::concepts::requirement_<ModelFnPtr>::failed> \
BOOST_PP_CAT(boost_concept_check,__LINE__) \
BOOST_ATTRIBUTE_UNUSED
}}
#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP

View File

@@ -0,0 +1,50 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP
# include <boost/type_traits/integral_constant.hpp>
# include <boost/config/workaround.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
namespace boost { namespace concepts {
namespace detail
{
// Here we implement the metafunction that detects whether a
// constraints metafunction exists
typedef char yes;
typedef char (&no)[2];
template <class Model, void (Model::*)()>
struct wrap_constraints {};
#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__)
// Work around the following bogus error in Sun Studio 11, by
// turning off the has_constraints function entirely:
// Error: complex expression not allowed in dependent template
// argument expression
inline no has_constraints_(...);
#else
template <class Model>
inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
inline no has_constraints_(...);
#endif
}
// This would be called "detail::has_constraints," but it has a strong
// tendency to show up in error messages.
template <class Model>
struct not_satisfied
{
BOOST_STATIC_CONSTANT(
bool
, value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) );
typedef boost::integral_constant<bool, value> type;
};
}} // namespace boost::concepts::detail
#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP

View File

@@ -0,0 +1,123 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# include <boost/preprocessor/cat.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
# include <boost/config.hpp>
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept/detail/has_constraints.hpp>
# include <boost/type_traits/conditional.hpp>
# endif
# ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable:4100)
# endif
namespace boost { namespace concepts {
template <class Model>
struct check
{
virtual void failed(Model* x)
{
x->~Model();
}
};
# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
struct failed {};
template <class Model>
struct check<failed ************ Model::************>
{
virtual void failed(Model* x)
{
x->~Model();
}
};
# endif
# ifdef BOOST_OLD_CONCEPT_SUPPORT
namespace detail
{
// No need for a virtual function here, since evaluating
// not_satisfied below will have already instantiated the
// constraints() member.
struct constraint {};
}
template <class Model>
struct require
: boost::conditional<
not_satisfied<Model>::value
, detail::constraint
# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
, check<Model>
# else
, check<failed ************ Model::************>
# endif
>::type
{};
# else
template <class Model>
struct require
# ifndef BOOST_NO_PARTIAL_SPECIALIZATION
: check<Model>
# else
: check<failed ************ Model::************>
# endif
{};
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
//
// The iterator library sees some really strange errors unless we
// do things this way.
//
template <class Model>
struct require<void(*)(Model)>
{
virtual void failed(Model*)
{
require<Model>();
}
};
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
enum \
{ \
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concepts::require<ModelFnPtr>) \
}
# else // Not vc-7.1
template <class Model>
require<Model>
require_(void(*)(Model));
# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \
enum \
{ \
BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concepts::require_((ModelFnPtr)0)) \
}
# endif
}}
# ifdef BOOST_MSVC
# pragma warning(pop)
# endif
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -0,0 +1,93 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
# define BOOST_CONCEPT_REQUIRES_DWA2006430_HPP
# include <boost/config.hpp>
# include <boost/concept/assert.hpp>
# include <boost/preprocessor/seq/for_each.hpp>
namespace boost {
// unaryfunptr_arg_type from parameter/aux_/parenthesized_type.hpp
namespace ccheck_aux {
// A metafunction that transforms void(*)(T) -> T
template <class UnaryFunctionPointer>
struct unaryfunptr_arg_type;
template <class Arg>
struct unaryfunptr_arg_type<void(*)(Arg)>
{
typedef Arg type;
};
template <>
struct unaryfunptr_arg_type<void(*)(void)>
{
typedef void type;
};
} // namespace ccheck_aux
// Template for use in handwritten assertions
template <class Model, class More>
struct requires_ : More
{
BOOST_CONCEPT_ASSERT((Model));
};
// Template for use by macros, where models must be wrapped in parens.
// This isn't in namespace detail to keep extra cruft out of resulting
// error messages.
template <class ModelFn>
struct _requires_
{
enum { value = 0 };
BOOST_CONCEPT_ASSERT_FN(ModelFn);
};
template <int check, class Result>
struct Requires_ : ::boost::ccheck_aux::unaryfunptr_arg_type<Result>
{
};
# if BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1010))
# define BOOST_CONCEPT_REQUIRES_(r,data,t) | (::boost::_requires_<void(*)t>::value)
# else
# define BOOST_CONCEPT_REQUIRES_(r,data,t) + (::boost::_requires_<void(*)t>::value)
# endif
#if defined(NDEBUG)
# define BOOST_CONCEPT_REQUIRES(models, result) \
typename ::boost::ccheck_aux::unaryfunptr_arg_type<void(*)result>::type
#elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
// Same thing as below without the initial typename
# define BOOST_CONCEPT_REQUIRES(models, result) \
::boost::Requires_< \
(0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
::boost::ccheck_aux::unaryfunptr_arg_type<void(*)result> \
>::type
#else
// This just ICEs on MSVC6 :(
# define BOOST_CONCEPT_REQUIRES(models, result) \
typename ::boost::Requires_< \
(0 BOOST_PP_SEQ_FOR_EACH(BOOST_CONCEPT_REQUIRES_, ~, models)), \
void(*)result \
>::type
#endif
// C++0x proposed syntax changed. This supports an older usage
#define BOOST_CONCEPT_WHERE(models,result) BOOST_CONCEPT_REQUIRES(models,result)
} // namespace boost::concept_check
#endif // BOOST_CONCEPT_REQUIRES_DWA2006430_HPP

View File

@@ -0,0 +1,43 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP
# define BOOST_CONCEPT_USAGE_DWA2006919_HPP
# include <boost/concept/assert.hpp>
# include <boost/config/workaround.hpp>
# include <boost/concept/detail/backward_compatibility.hpp>
namespace boost { namespace concepts {
template <class Model>
struct usage_requirements
{
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnonnull"
# endif
~usage_requirements() { ((Model*)0)->~Model(); }
# if defined(BOOST_GCC) && (BOOST_GCC >= 110000)
# pragma GCC diagnostic pop
# endif
};
# if BOOST_WORKAROUND(__GNUC__, <= 3)
# define BOOST_CONCEPT_USAGE(model) \
model(); /* at least 2.96 and 3.4.3 both need this :( */ \
BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
~model()
# else
# define BOOST_CONCEPT_USAGE(model) \
BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
~model()
# endif
}} // namespace boost::concepts
#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP

View File

@@ -0,0 +1,670 @@
//
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Revision History:
//
// 17 July 2001: Added const to some member functions. (Jeremy Siek)
// 05 May 2001: Removed static dummy_cons object. (Jeremy Siek)
// See http://www.boost.org/libs/concept_check for documentation.
#ifndef BOOST_CONCEPT_ARCHETYPES_HPP
#define BOOST_CONCEPT_ARCHETYPES_HPP
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <functional>
#include <iterator> // iterator tags
#include <cstddef> // std::ptrdiff_t
namespace boost {
//===========================================================================
// Basic Archetype Classes
namespace detail {
class dummy_constructor { };
}
// A type that models no concept. The template parameter
// is only there so that null_archetype types can be created
// that have different type.
template <class T = int>
class null_archetype {
private:
null_archetype() { }
null_archetype(const null_archetype&) { }
null_archetype& operator=(const null_archetype&) { return *this; }
public:
null_archetype(detail::dummy_constructor) { }
#ifndef __MWERKS__
template <class TT>
friend void dummy_friend(); // just to avoid warnings
#endif
};
// This is a helper class that provides a way to get a reference to
// an object. The get() function will never be called at run-time
// (nothing in this file will) so this seemingly very bad function
// is really quite innocent. The name of this class needs to be
// changed.
template <class T>
class static_object
{
public:
static T& get()
{
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
return *reinterpret_cast<T*>(0);
#else
static char d[sizeof(T)];
return *reinterpret_cast<T*>(d);
#endif
}
};
template <class Base = null_archetype<> >
class default_constructible_archetype : public Base {
public:
default_constructible_archetype()
: Base(static_object<detail::dummy_constructor>::get()) { }
default_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base = null_archetype<> >
class assignable_archetype : public Base {
assignable_archetype() { }
assignable_archetype(const assignable_archetype&) { }
public:
assignable_archetype& operator=(const assignable_archetype&) {
return *this;
}
assignable_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base = null_archetype<> >
class copy_constructible_archetype : public Base {
public:
copy_constructible_archetype()
: Base(static_object<detail::dummy_constructor>::get()) { }
copy_constructible_archetype(const copy_constructible_archetype&)
: Base(static_object<detail::dummy_constructor>::get()) { }
copy_constructible_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base = null_archetype<> >
class sgi_assignable_archetype : public Base {
public:
sgi_assignable_archetype(const sgi_assignable_archetype&)
: Base(static_object<detail::dummy_constructor>::get()) { }
sgi_assignable_archetype& operator=(const sgi_assignable_archetype&) {
return *this;
}
sgi_assignable_archetype(const detail::dummy_constructor& x) : Base(x) { }
};
struct default_archetype_base {
default_archetype_base(detail::dummy_constructor) { }
};
// Careful, don't use same type for T and Base. That results in the
// conversion operator being invalid. Since T is often
// null_archetype, can't use null_archetype for Base.
template <class T, class Base = default_archetype_base>
class convertible_to_archetype : public Base {
private:
convertible_to_archetype() { }
convertible_to_archetype(const convertible_to_archetype& ) { }
convertible_to_archetype& operator=(const convertible_to_archetype&)
{ return *this; }
public:
convertible_to_archetype(detail::dummy_constructor x) : Base(x) { }
operator const T&() const { return static_object<T>::get(); }
};
template <class T, class Base = default_archetype_base>
class convertible_from_archetype : public Base {
private:
convertible_from_archetype() { }
convertible_from_archetype(const convertible_from_archetype& ) { }
convertible_from_archetype& operator=(const convertible_from_archetype&)
{ return *this; }
public:
convertible_from_archetype(detail::dummy_constructor x) : Base(x) { }
convertible_from_archetype(const T&) { }
convertible_from_archetype& operator=(const T&)
{ return *this; }
};
class boolean_archetype {
public:
boolean_archetype(const boolean_archetype&) { }
operator bool() const { return true; }
boolean_archetype(detail::dummy_constructor) { }
private:
boolean_archetype() { }
boolean_archetype& operator=(const boolean_archetype&) { return *this; }
};
template <class Base = null_archetype<> >
class equality_comparable_archetype : public Base {
public:
equality_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base>
boolean_archetype
operator==(const equality_comparable_archetype<Base>&,
const equality_comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base>
boolean_archetype
operator!=(const equality_comparable_archetype<Base>&,
const equality_comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base = null_archetype<> >
class equality_comparable2_first_archetype : public Base {
public:
equality_comparable2_first_archetype(detail::dummy_constructor x)
: Base(x) { }
};
template <class Base = null_archetype<> >
class equality_comparable2_second_archetype : public Base {
public:
equality_comparable2_second_archetype(detail::dummy_constructor x)
: Base(x) { }
};
template <class Base1, class Base2>
boolean_archetype
operator==(const equality_comparable2_first_archetype<Base1>&,
const equality_comparable2_second_archetype<Base2>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base1, class Base2>
boolean_archetype
operator!=(const equality_comparable2_first_archetype<Base1>&,
const equality_comparable2_second_archetype<Base2>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base = null_archetype<> >
class less_than_comparable_archetype : public Base {
public:
less_than_comparable_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base>
boolean_archetype
operator<(const less_than_comparable_archetype<Base>&,
const less_than_comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base = null_archetype<> >
class comparable_archetype : public Base {
public:
comparable_archetype(detail::dummy_constructor x) : Base(x) { }
};
template <class Base>
boolean_archetype
operator<(const comparable_archetype<Base>&,
const comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base>
boolean_archetype
operator<=(const comparable_archetype<Base>&,
const comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base>
boolean_archetype
operator>(const comparable_archetype<Base>&,
const comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
template <class Base>
boolean_archetype
operator>=(const comparable_archetype<Base>&,
const comparable_archetype<Base>&)
{
return boolean_archetype(static_object<detail::dummy_constructor>::get());
}
// The purpose of the optags is so that one can specify
// exactly which types the operator< is defined between.
// This is useful for allowing the operations:
//
// A a; B b;
// a < b
// b < a
//
// without also allowing the combinations:
//
// a < a
// b < b
//
struct optag1 { };
struct optag2 { };
struct optag3 { };
#define BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(OP, NAME) \
template <class Base = null_archetype<>, class Tag = optag1 > \
class NAME##_first_archetype : public Base { \
public: \
NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
}; \
\
template <class Base = null_archetype<>, class Tag = optag1 > \
class NAME##_second_archetype : public Base { \
public: \
NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
}; \
\
template <class BaseFirst, class BaseSecond, class Tag> \
boolean_archetype \
operator OP (const NAME##_first_archetype<BaseFirst, Tag>&, \
const NAME##_second_archetype<BaseSecond, Tag>&) \
{ \
return boolean_archetype(static_object<detail::dummy_constructor>::get()); \
}
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(==, equal_op)
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(!=, not_equal_op)
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<, less_than_op)
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(<=, less_equal_op)
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>, greater_than_op)
BOOST_DEFINE_BINARY_PREDICATE_ARCHETYPE(>=, greater_equal_op)
#define BOOST_DEFINE_OPERATOR_ARCHETYPE(OP, NAME) \
template <class Base = null_archetype<> > \
class NAME##_archetype : public Base { \
public: \
NAME##_archetype(detail::dummy_constructor x) : Base(x) { } \
NAME##_archetype(const NAME##_archetype&) \
: Base(static_object<detail::dummy_constructor>::get()) { } \
NAME##_archetype& operator=(const NAME##_archetype&) { return *this; } \
}; \
template <class Base> \
NAME##_archetype<Base> \
operator OP (const NAME##_archetype<Base>&,\
const NAME##_archetype<Base>&) \
{ \
return \
NAME##_archetype<Base>(static_object<detail::dummy_constructor>::get()); \
}
BOOST_DEFINE_OPERATOR_ARCHETYPE(+, addable)
BOOST_DEFINE_OPERATOR_ARCHETYPE(-, subtractable)
BOOST_DEFINE_OPERATOR_ARCHETYPE(*, multipliable)
BOOST_DEFINE_OPERATOR_ARCHETYPE(/, dividable)
BOOST_DEFINE_OPERATOR_ARCHETYPE(%, modable)
// As is, these are useless because of the return type.
// Need to invent a better way...
#define BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(OP, NAME) \
template <class Return, class Base = null_archetype<> > \
class NAME##_first_archetype : public Base { \
public: \
NAME##_first_archetype(detail::dummy_constructor x) : Base(x) { } \
}; \
\
template <class Return, class Base = null_archetype<> > \
class NAME##_second_archetype : public Base { \
public: \
NAME##_second_archetype(detail::dummy_constructor x) : Base(x) { } \
}; \
\
template <class Return, class BaseFirst, class BaseSecond> \
Return \
operator OP (const NAME##_first_archetype<Return, BaseFirst>&, \
const NAME##_second_archetype<Return, BaseSecond>&) \
{ \
return Return(static_object<detail::dummy_constructor>::get()); \
}
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(+, plus_op)
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(*, time_op)
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(/, divide_op)
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(-, subtract_op)
BOOST_DEFINE_BINARY_OPERATOR_ARCHETYPE(%, mod_op)
//===========================================================================
// Function Object Archetype Classes
template <class Return>
class generator_archetype {
public:
const Return& operator()() {
return static_object<Return>::get();
}
};
class void_generator_archetype {
public:
void operator()() { }
};
template <class Arg, class Return>
class unary_function_archetype {
private:
unary_function_archetype() { }
public:
unary_function_archetype(detail::dummy_constructor) { }
const Return& operator()(const Arg&) const {
return static_object<Return>::get();
}
};
template <class Arg1, class Arg2, class Return>
class binary_function_archetype {
private:
binary_function_archetype() { }
public:
binary_function_archetype(detail::dummy_constructor) { }
const Return& operator()(const Arg1&, const Arg2&) const {
return static_object<Return>::get();
}
};
template <class Arg>
class unary_predicate_archetype {
typedef boolean_archetype Return;
unary_predicate_archetype() { }
public:
unary_predicate_archetype(detail::dummy_constructor) { }
const Return& operator()(const Arg&) const {
return static_object<Return>::get();
}
};
template <class Arg1, class Arg2, class Base = null_archetype<> >
class binary_predicate_archetype {
typedef boolean_archetype Return;
binary_predicate_archetype() { }
public:
binary_predicate_archetype(detail::dummy_constructor) { }
const Return& operator()(const Arg1&, const Arg2&) const {
return static_object<Return>::get();
}
};
//===========================================================================
// Iterator Archetype Classes
template <class T, int I = 0>
class input_iterator_archetype
{
private:
typedef input_iterator_archetype self;
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
struct reference {
operator const value_type&() const { return static_object<T>::get(); }
};
typedef const T* pointer;
typedef std::ptrdiff_t difference_type;
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return reference(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
};
template <class T>
class input_iterator_archetype_no_proxy
{
private:
typedef input_iterator_archetype_no_proxy self;
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef const T& reference;
typedef const T* pointer;
typedef std::ptrdiff_t difference_type;
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
};
template <class T>
struct output_proxy {
output_proxy& operator=(const T&) { return *this; }
};
template <class T>
class output_iterator_archetype
{
public:
typedef output_iterator_archetype self;
public:
typedef std::output_iterator_tag iterator_category;
typedef output_proxy<T> value_type;
typedef output_proxy<T> reference;
typedef void pointer;
typedef void difference_type;
output_iterator_archetype(detail::dummy_constructor) { }
output_iterator_archetype(const self&) { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return output_proxy<T>(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
private:
output_iterator_archetype() { }
};
template <class T>
class input_output_iterator_archetype
{
private:
typedef input_output_iterator_archetype self;
struct in_out_tag : public std::input_iterator_tag, public std::output_iterator_tag { };
public:
typedef in_out_tag iterator_category;
typedef T value_type;
struct reference {
reference& operator=(const T&) { return *this; }
operator value_type() { return static_object<T>::get(); }
};
typedef const T* pointer;
typedef std::ptrdiff_t difference_type;
input_output_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return reference(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
};
template <class T>
class forward_iterator_archetype
{
public:
typedef forward_iterator_archetype self;
public:
typedef std::forward_iterator_tag iterator_category;
typedef T value_type;
typedef const T& reference;
typedef T const* pointer;
typedef std::ptrdiff_t difference_type;
forward_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
};
template <class T>
class mutable_forward_iterator_archetype
{
public:
typedef mutable_forward_iterator_archetype self;
public:
typedef std::forward_iterator_tag iterator_category;
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
mutable_forward_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
};
template <class T>
class bidirectional_iterator_archetype
{
public:
typedef bidirectional_iterator_archetype self;
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef const T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
bidirectional_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
self& operator--() { return *this; }
self operator--(int) { return *this; }
};
template <class T>
class mutable_bidirectional_iterator_archetype
{
public:
typedef mutable_bidirectional_iterator_archetype self;
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
mutable_bidirectional_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
self& operator--() { return *this; }
self operator--(int) { return *this; }
};
template <class T>
class random_access_iterator_archetype
{
public:
typedef random_access_iterator_archetype self;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef const T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
random_access_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
self& operator--() { return *this; }
self operator--(int) { return *this; }
reference operator[](difference_type) const
{ return static_object<T>::get(); }
self& operator+=(difference_type) { return *this; }
self& operator-=(difference_type) { return *this; }
difference_type operator-(const self&) const
{ return difference_type(); }
self operator+(difference_type) const { return *this; }
self operator-(difference_type) const { return *this; }
bool operator<(const self&) const { return true; }
bool operator<=(const self&) const { return true; }
bool operator>(const self&) const { return true; }
bool operator>=(const self&) const { return true; }
};
template <class T>
random_access_iterator_archetype<T>
operator+(typename random_access_iterator_archetype<T>::difference_type,
const random_access_iterator_archetype<T>& x)
{ return x; }
template <class T>
class mutable_random_access_iterator_archetype
{
public:
typedef mutable_random_access_iterator_archetype self;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
mutable_random_access_iterator_archetype() { }
self& operator=(const self&) { return *this; }
bool operator==(const self&) const { return true; }
bool operator!=(const self&) const { return true; }
reference operator*() const { return static_object<T>::get(); }
self& operator++() { return *this; }
self operator++(int) { return *this; }
self& operator--() { return *this; }
self operator--(int) { return *this; }
reference operator[](difference_type) const
{ return static_object<T>::get(); }
self& operator+=(difference_type) { return *this; }
self& operator-=(difference_type) { return *this; }
difference_type operator-(const self&) const
{ return difference_type(); }
self operator+(difference_type) const { return *this; }
self operator-(difference_type) const { return *this; }
bool operator<(const self&) const { return true; }
bool operator<=(const self&) const { return true; }
bool operator>(const self&) const { return true; }
bool operator>=(const self&) const { return true; }
};
template <class T>
mutable_random_access_iterator_archetype<T>
operator+
(typename mutable_random_access_iterator_archetype<T>::difference_type,
const mutable_random_access_iterator_archetype<T>& x)
{ return x; }
} // namespace boost
#endif // BOOST_CONCEPT_ARCHETYPES_H

View File

@@ -0,0 +1,25 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP
namespace boost {
template <class ModelFn>
struct concept_check;
template <class Model>
struct concept_check<void(*)(Model)>
{
enum { instantiate = sizeof((((Model*)0)->~Model()), 3) };
};
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
boost::concept_check<void(*)ModelInParens>::instantiate \
}
} // namespace boost::concept_checking
#endif // BOOST_CONCEPT_CHECK_BORLAND_DWA2006429_HPP

View File

@@ -0,0 +1,82 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept_check/has_constraints.hpp>
# include <boost/type_traits/conditional.hpp>
# endif
// This implementation works on GCC and Comeau, but has actually been
// fairly carefully tuned to work on GCC versions starting with
// gcc-2.95.x. If you're trying to get an additional compiler to pass
// the tests you might consider breaking out a separate gcc.hpp and
// starting over on the general case.
namespace boost
{
namespace concept_checking
{
template <void(*)()> struct instantiate {};
}
template <class ModelFn> struct concept_check_;
template <class Model>
void concept_check_failed()
{
((Model*)0)->~Model();
}
template <class Model>
struct concept_check
{
concept_checking::instantiate<concept_check_failed<Model> > x;
enum { instantiate = 1 };
};
# ifdef BOOST_OLD_CONCEPT_SUPPORT
template <class Model>
void constraint_check_failed()
{
((Model*)0)->constraints();
}
template <class Model>
struct constraint_check
{
concept_checking::instantiate<constraint_check_failed<Model> > x;
enum { instantiate = 1 };
};
template <class Model>
struct concept_check_<void(*)(Model)>
: conditional<
concept_checking::has_constraints<Model>::value
, constraint_check<Model>
, concept_check<Model>
>::type
{};
# else
template <class Model>
struct concept_check_<void(*)(Model)>
: concept_check<Model>
{};
# endif
// Usage, in class or function context:
//
// BOOST_CONCEPT_ASSERT((UnaryFunctionConcept<F,bool,int>));
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
::boost::concept_check_<void(*) ModelInParens>::instantiate \
}
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -0,0 +1,31 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP
namespace boost { namespace concept_checking {
// Here we implement the "metafunction" that detects whether a
// constraints metafunction exists
typedef char yes;
typedef char (&no)[2];
template <class Model, void (Model::*)()>
struct wrap_constraints {};
template <class Model>
inline yes has_constraints_(Model*, wrap_constraints<Model,&Model::constraints>* = 0);
inline no has_constraints_(...);
template <class Model>
struct has_constraints
{
BOOST_STATIC_CONSTANT(
bool
, value = sizeof( concept_checking::has_constraints_((Model*)0) ) == 1 );
};
}} // namespace boost::concept_checking
#endif // BOOST_CONCEPT_CHECK_HAS_CONSTRAINTS_DWA2006429_HPP

View File

@@ -0,0 +1,90 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP
# ifdef BOOST_OLD_CONCEPT_SUPPORT
# include <boost/concept_check/has_constraints.hpp>
# include <boost/type_traits/conditional.hpp>
# endif
namespace boost
{
namespace concept_checking
{
template <class Model>
struct concept_check_
{
virtual void failed(Model* x)
{
x->~Model();
}
};
}
# ifdef BOOST_OLD_CONCEPT_SUPPORT
namespace concept_checking
{
template <class Model>
struct constraint_check
{
virtual void failed(Model* x)
{
x->constraints();
}
};
}
template <class Model>
struct concept_check
: conditional<
concept_checking::has_constraints<Model>::value
, concept_checking::constraint_check<Model>
, concept_checking::concept_check_<Model>
>::type
{};
# else
template <class Model>
struct concept_check
: concept_checking::concept_check_<Model>
{};
# endif
# if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
//
// The iterator library sees some really strange errors unless we
// use partial specialization to extract the model type with
// msvc-7.1
//
template <class Model>
struct concept_check<void(*)(Model)>
: concept_check<Model>
{ };
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concept_check<void(*) ModelInParens>) \
}
# else
template <class Model>
concept_check<Model>
concept_check_(void(*)(Model));
# define BOOST_CONCEPT_ASSERT( ModelInParens ) \
enum { BOOST_PP_CAT(boost_concept_check,__LINE__) = \
sizeof(::boost::concept_check_((void(*) ModelInParens)0)) \
}
# endif
}
#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP

View File

@@ -0,0 +1,13 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=concept_check.htm">
</head>
<body>
Automatic redirection failed, please go to
<a href="concept_check.htm">concept_check.htm</a>.&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<explicit-failures-markup>
<!-- concept_check -->
<library name="concept_check">
<test name="class_concept_fail_expected">
<mark-failure>
<toolset name="cw-8.3*"/>
<note author="B. Dawes" refid="3"/>
</mark-failure>
</test>
<test name="class_concept_fail_expected">
<mark-failure>
<toolset name="borland-5*"/>
<toolset name="msvc-6.5*"/>
<toolset name="msvc-7.0"/>
<note author="Jeremy Siek"/>
</mark-failure>
</test>
<test name="stl_concept_check">
<mark-failure>
<toolset name="hp_cxx*"/>
<note author="Markus Schoepflin" date="09 Dec 2007">
This version of the Rogue Wave library fails to provide all
needed addition operators for the iterator type and the
difference type of std::deque.
</note>
</mark-failure>
</test>
</library>
</explicit-failures-markup>

View File

@@ -0,0 +1,16 @@
{
"key": "concept_check",
"name": "Concept Check",
"authors": [
"Jeremy Siek"
],
"description": "Tools for generic programming.",
"category": [
"Correctness",
"Generic"
],
"maintainers": [
"Jeremy Siek <jeremy.siek -at- gmail.com>"
],
"cxxstd": "03"
}

View File

@@ -0,0 +1,144 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<title>Programming With Concepts</title>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<link rel="stylesheet" href="../../rst.css" type="text/css" />
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="programming-with-concepts" id=
"programming-with-concepts">Programming with Concepts</a></h2>
<p>The process of deciding how to group requirements into concepts and
deciding which concepts to use in each algorithm is perhaps the most
difficult (yet most important) part of building a generic library. A
guiding principle to use during this process is one we call the
<i>requirement minimization principle</i>.</p>
<p><b>Requirement Minimization Principle:</b> Minimize the requirements on
the input parameters of a component to increase its reusability.</p>
<p>There is natural tension in this statement. By definition, the input
parameters must be used by the component in order for the component to
accomplish its task (by ``component'' we mean a function or class
template). The challenge then is to implement the component in such a way
that makes the fewest assumptions (the minimum requirements) about the
inputs while still accomplishing the task.</p>
<p>The traditional notions of <i>abstraction</i> tie in directly to the
idea of minimal requirements. The more abstract the input, the fewer the
requirements. Thus, concepts are simply the embodiment of generic abstract
data types in C++ template programming.</p>
<p>When designing the concepts for some problem domain it is important to
keep in mind their purpose, namely to express the requirements for the
input to the components. With respect to the requirement minimization
principle, this means we want to minimize concepts.
<!-- the following discussion does not match the Standard definition
of LessThanComparable and needs to be changed -Jeremy
<p>
It is important to note, however, that
minimizing concepts does not mean simply
reducing the number of valid expressions
in the concept.
For example, the
<tt>std::stable_sort()</tt> function requires that the value type of
the iterator be <a
href="http://www.boost.org/sgi/stl/LessThanComparable.html">
LessThanComparable</a>, which not only
includes <tt>operator&lt;()</tt>, but also <tt>operator&gt;()</tt>,
<tt>operator&lt;=()</tt>, and <tt>operator&gt;=()</tt>.
It turns out that <tt>std::stable_sort()</tt> only uses
<tt>operator&lt;()</tt>. The question then arises: should
<tt>std::stable_sort()</tt> be specified in terms of the concept
<a
href="http://www.boost.org/sgi/stl/LessThanComparable.html">
LessThanComparable</a> or in terms of a concept that only
requires <tt>operator&lt;()</tt>?
<p>
We remark first that the use of <a
href="http://www.boost.org/sgi/stl/LessThanComparable.html">
LessThanComparable</a> does not really violate the requirement
minimization principle because all of the other operators can be
trivially implemented in terms of <tt>operator&lt;()</tt>. By
``trivial'' we mean one line of code and a constant run-time cost.
More fundamentally, however, the use of <a
href="http://www.boost.org/sgi/stl/LessThanComparable.html">
LessThanComparable</a> does not violate the requirement minimization
principle because all of the comparison operators (<tt>&lt;</tt>,
<tt>></tt>, <tt><=</tt>, <tt>>=</tt>) are conceptually equivalent (in
a mathematical sense). Adding conceptually equivalent valid
expressions is not a violation of the requirement minimization
principle because no new semantics are being added === only new
syntax. The added syntax increases re-usability.
<p>
For example,
the
maintainer of the <tt>std::stable_sort()</tt> may some day change the
implementation in places to use <tt>operator>()</tt> instead of
<tt>operator<()</tt>, since, after all, they are equivalent. Since the
requirements are part of the public interface, such a change could
potentially break client code. If instead
<a
href="http://www.boost.org/sgi/stl/LessThanComparable.html">
LessThanComparable</a> is given as the requirement for
<tt>std::stable_sort()</tt>, then the maintainer is given a reasonable
amount of flexibility within which to work.
--></p>
<p>Minimality in concepts is a property associated with the underlying
semantics of the problem domain being represented. In the problem domain of
basic containers, requiring traversal in a single direction is a smaller
requirement than requiring traversal in both directions (hence the
distinction between <a href=
"http://www.boost.org/sgi/stl/ForwardIterator.html">ForwardIterator</a> and
<a href=
"http://www.boost.org/sgi/stl/BidirectionalIterator.html">BidirectionalIterator</a>).
The semantic difference can be easily seen in the difference between the
set of concrete data structures that have forward iterators versus the set
that has bidirectional iterators. For example, singly-linked lists would
fall in the set of data structures having forward iterators, but not
bidirectional iterators. In addition, the set of algorithms that one can
implement using only forward iterators is quite different than the set that
can be implemented with bidirectional iterators. Because of this, it is
important to factor families of requirements into rather fine-grained
concepts. For example, the requirements for iterators are factored into the
six STL iterator concepts (trivial, output, input, forward, bidirectional,
and random access).</p>
<p><a href="./implementation.htm">Next: Implementation</a><br />
<a href="./concept_covering.htm">Prev: Concept Covering and
Archetypes</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>),
2007 <a href="mailto:dave@boost-consulting.com">David Abrahams</a>.
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,418 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="../../rst.css" type="text/css" />
<title>Boost Concept Checking Reference</title>
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="reference" id="reference">Reference</a></h2>
<ol>
<li><a href="#macros">Macros</a></li>
<li><a href="#basic-concepts">Basic Concept Checking Classes</a></li>
<li><a href="#iterator-concepts">Iterator Concept Checking
Classes</a></li>
<li><a href="#function-object-concepts">Function Object Concept Checking
Classes</a></li>
<li><a href="#container-concepts">Container Concept Checking
Classes</a></li>
<li><a href="#basic-archetype">Basic Archetype Classes</a></li>
<li><a href="#iterator-archetype">Iterator Archetype Classes</a></li>
<li><a href="#function-object-archetype">Function Object Archetype
Classes</a></li>
<li><a href="#container-archetype">Container Archetype Classes</a></li>
<li><a href="#deprecated-functions">Deprecated Functions</a></li>
<li><a href="#deprecated-macros">Deprecated Macros</a></li>
<li><a href="#deprecated-concept-checking-classes">Deprecated Concept
Checking Classes</a></li>
</ol>
<h3><a name="macros" id="macros">Macros</a></h3>
<pre>
#include "boost/concept/assert.hpp"
BOOST_CONCEPT_ASSERT((<em>concept checking class template specialization</em>));
</pre>
<p><strong>Effects:</strong> causes a compilation failure if the concept is
not satisfied.<br />
<strong>Note:</strong> this macro can be used at global, class, or function
scope.</p>
<pre>
#include "boost/concept/requires.hpp"
<font color="gray">template &lt;<em>template parameters</em>&gt;</font>
BOOST_CONCEPT_REQUIRES(
((<em>concept checking class template specialization<sub>1</sub></em>))
((<em>concept checking class template specialization<sub>2</sub></em>))…
((<em>concept checking class template specialization<sub>n</sub></em>))<strong>,</strong>
(<em>function return type</em>)
) <font color="gray"><em>function_template_name</em>(…<em>function parameters</em>…)</font>
</pre>
<p><strong>Effects:</strong> causes a compilation failure if the
given concepts are not satisfied.<br />
<strong>Note:</strong> this macro is intended to be used in place of
a function template's return type.</p>
<h3><a name="basic-concepts" id="basic-concepts">Basic Concept Checking
Classes</a></h3>
<pre>
#include "boost/concept_check.hpp"
template &lt;class T&gt;
struct Integer; // Is T a built-in integer type?
template &lt;class T&gt;
struct SignedInteger; // Is T a built-in signed integer type?
template &lt;class T&gt;
struct UnsignedInteger; // Is T a built-in unsigned integer type?
template &lt;class X, class Y&gt;
struct Convertible; // Is X convertible to Y?
template &lt;class T&gt;
struct <a href=
"../utility/Assignable.html">Assignable</a>; // Standard ref 23.1
template &lt;class T&gt;
struct SGI<a href=
"http://www.boost.org/sgi/stl/Assignable.html">Assignable</a>;
template &lt;class T&gt;
struct <a href=
"http://www.boost.org/sgi/stl/DefaultConstructible.html">DefaultConstructible</a>;
template &lt;class T&gt;
struct <a href=
"../utility/CopyConstructible.html">CopyConstructible</a>; // Standard ref 20.1.3
template &lt;class T&gt;
struct <a href=
"http://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</a>; // Standard ref 20.1.1
template &lt;class T&gt;
struct <a href=
"../utility/LessThanComparable.html">LessThanComparable</a>; // Standard ref 20.1.2
template &lt;class T&gt;
struct Comparable; // The SGI STL <a href=
"http://www.boost.org/sgi/stl/LessThanComparable.html">LessThanComparable</a> concept
</pre>
<h3><a name="iterator-concepts" id="iterator-concepts">Iterator Concept
Checking Classes</a></h3>
<pre>
template &lt;class Iter&gt;
struct <a href=
"http://www.boost.org/sgi/stl/InputIterator.html">InputIterator</a>; // Standard ref 24.1.1 Table 72
template &lt;class Iter, class T&gt;
struct <a href=
"http://www.boost.org/sgi/stl/OutputIterator.html">OutputIterator</a>; // Standard ref 24.1.2 Table 73
template &lt;class Iter&gt;
struct <a href=
"http://www.boost.org/sgi/stl/ForwardIterator.html">ForwardIterator</a>; // Standard ref 24.1.3 Table 74
template &lt;class Iter&gt;
struct Mutable_ForwardIterator;
template &lt;class Iter&gt;
struct <a href=
"http://www.boost.org/sgi/stl/BidirectionalIterator.html">BidirectionalIterator</a>; // Standard ref 24.1.4 Table 75
template &lt;class Iter&gt;
struct Mutable_BidirectionalIterator;
template &lt;class Iter&gt;
struct <a href=
"http://www.boost.org/sgi/stl/RandomAccessIterator.html">RandomAccessIterator</a>; // Standard ref 24.1.5 Table 76
template &lt;class Iter&gt;
struct Mutable_RandomAccessIterator;
</pre>
<h3><a name="function-object-concepts" id=
"function-object-concepts">Function Object Concept Checking
Classes</a></h3>
<pre>
#include "boost/concept_check.hpp"
template &lt;class Func, class Return&gt;
struct <a href="http://www.boost.org/sgi/stl/Generator.html">Generator</a>;
template &lt;class Func, class Return, class Arg&gt;
struct <a href=
"http://www.boost.org/sgi/stl/UnaryFunction.html">UnaryFunction</a>;
template &lt;class Func, class Return, class First, class Second&gt;
struct <a href=
"http://www.boost.org/sgi/stl/BinaryFunction.html">BinaryFunction</a>;
template &lt;class Func, class Arg&gt;
struct Unary<a href=
"http://www.boost.org/sgi/stl/Predicate.html">Predicate</a>;
template &lt;class Func, class First, class Second&gt;
struct <a href=
"http://www.boost.org/sgi/stl/BinaryPredicate.html">BinaryPredicate</a>;
template &lt;class Func, class First, class Second&gt;
struct Const_BinaryPredicate;
template &lt;class Func, class Return&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AdaptableGenerator.html">AdaptableGenerator</a>;
template &lt;class Func, class Return, class Arg&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>;
template &lt;class Func, class First, class Second&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AdaptableBinaryFunction.html">AdaptableBinaryFunction</a>;
template &lt;class Func, class Arg&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AdaptablePredicate.html">AdaptablePredicate</a>;
template &lt;class Func, class First, class Second&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AdaptableBinaryPredicate.html">AdaptableBinaryPredicate</a>;
</pre>
<h3><a name="container-concepts" id="container-concepts">Container Concept
Checking Classes</a></h3>
<pre>
#include "boost/concept_check.hpp"
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/Container.html">Container</a>; // Standard ref 23.1 Table 65
template &lt;class C&gt;
struct Mutable_Container;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/ForwardContainer.html">ForwardContainer</a>;
template &lt;class C&gt;
struct Mutable_ForwardContainer;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/ReversibleContainer.html">ReversibleContainer</a>; // Standard ref 23.1 Table 66
template &lt;class C&gt;
struct Mutable_ReversibleContainer;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/RandomAccessContainer.html">RandomAccessContainer</a>;
template &lt;class C&gt;
struct Mutable_RandomAccessContainer;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/Sequence.html">Sequence</a>; // Standard ref 23.1.1
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/FrontInsertionSequence.html">FrontInsertionSequence</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/BackInsertionSequence.html">BackInsertionSequence</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/AssociativeContainer.html">AssociativeContainer</a>; // Standard ref 23.1.2 Table 69
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/UniqueAssociativeContainer.html">UniqueAssociativeContainer</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/MultipleAssociativeContainer.html">MultipleAssociativeContainer</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/SimpleAssociativeContainer.html">SimpleAssociativeContainer</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/PairAssociativeContainer.html">PairAssociativeContainer</a>;
template &lt;class C&gt;
struct <a href=
"http://www.boost.org/sgi/stl/SortedAssociativeContainer.html">SortedAssociativeContainer</a>;
template &lt;class C&gt;
struct <a href=
"../utility/Collection.html">Collection</a>;
</pre>
<h3><a name="basic-archetype" id="basic-archetype">Basic Archetype
Classes</a></h3>
<pre>
#include "boost/concept_archetype.hpp"
template &lt;class T = int&gt;
class null_archetype; // A type that models no concepts.
template &lt;class Base = null_archetype&gt;
class default_constructible_archetype;
template &lt;class Base = null_archetype&gt;
class assignable_archetype;
template &lt;class Base = null_archetype&gt;
class copy_constructible_archetype;
template &lt;class Base = null_archetype&gt;
class equality_comparable_archetype;
template &lt;class T, class Base = null_archetype&gt;
class convertible_to_archetype;
</pre>
<h3><a name="iterator-archetype" id="iterator-archetype">Iterator Archetype
Classes</a></h3>
<pre>
#include "boost/concept_archetype.hpp"
template &lt;class ValueType&gt;
class trivial_iterator_archetype;
template &lt;class ValueType&gt;
class mutable_trivial_iterator_archetype;
template &lt;class ValueType&gt;
class input_iterator_archetype;
template &lt;class ValueType&gt;
class forward_iterator_archetype;
template &lt;class ValueType&gt;
class bidirectional_iterator_archetype;
template &lt;class ValueType&gt;
class random_access_iterator_archetype;
</pre>
<h3><a name="function-object-archetype" id=
"function-object-archetype">Function Object Archetype Classes</a></h3>
<pre>
#include "boost/concept_archetype.hpp"
template &lt;class Arg, class Return&gt;
class unary_function_archetype;
template &lt;class Arg1, class Arg2, class Return&gt;
class binary_function_archetype;
template &lt;class Arg&gt;
class predicate_archetype;
template &lt;class Arg1, class Arg2&gt;
class binary_predicate_archetype;
</pre>
<h3><a name="container-archetype" id="container-archetype">Container
Archetype Classes</a></h3>
<pre>
UNDER CONSTRUCTION
</pre>
<h3><a name="deprecated-functions" id="deprecated-functions">Deprecated
Functions</a></h3>
<pre>
#include "boost/concept_check.hpp"
template &lt;class Concept&gt;
void function_requires();
</pre>
<p><code>function_requires()</code> has been deprecated in favor of <code>BOOST_CONCEPT_ASSERT</code>.
This means that <del><code>function_requires< Concept<Type> >();</code></del>
becomes <code>BOOST_CONCEPT_ASSERT((Concept<Type>));</code>
(don't forget to <code>#include &quot;boost/concept/assert.hpp&quot;</code>).
<h3><a name="deprecated-macros" id="deprecated-macros">Deprecated
Macros</a></h3>
<pre>
#include "boost/concept_check.hpp"
// Apply concept checks in class definitions.
BOOST_CLASS_REQUIRE(<i>type</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE2(<i>type1</i>, <i>type2</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE3(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>namespace-of-concept</i>, <i>concept</i>);
BOOST_CLASS_REQUIRE4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>namespace-of-concept</i>, <i>concept</i>);
// Apply concept checks in class definitions.
BOOST_CLASS_REQUIRES(<i>type</i>, <i>concept</i>);
BOOST_CLASS_REQUIRES2(<i>type1</i>, <i>type2</i>, <i>concept</i>);
BOOST_CLASS_REQUIRES3(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>concept</i>);
BOOST_CLASS_REQUIRES4(<i>type1</i>, <i>type2</i>, <i>type3</i>, <i>type4</i>, <i>concept</i>);
</pre>
<h3><a name="deprecated-concept-checking-classes" id=
"deprecated-concept-checking-classes">Deprecated Concept Checking
Classes</a></h3>
<p>For each of the concepts documented here, the library includes an
identical concept checking class whose name ends in
<code>Concept</code>” For example, in
addition to <code>RandomAccessIterator</code>, the library defines a
<code>RandomAccessIteratorConcept</code> class template.</p>
<p><a href="./concept_check.htm">Back to Introduction</a><br />
<a href="./implementation.htm">Prev: Implementation</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>), 2007
<a href="mailto:dave@boost-consulting.com">David Abrahams</a>.</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,25 @@
# Copyright David Abrahams, Jeremy Siek, Vladimir Prus
# 2006. Distributed under the Boost Software License, Version
# 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import testing ;
test-suite concept_check
: [ link stl_concept_covering.cpp ]
[ run stl_concept_check.cpp ]
[ run concept_check_test.cpp ]
[ run class_concept_check_test.cpp ]
[ compile-fail concept_check_fail_expected.cpp ]
[ compile-fail class_concept_fail_expected.cpp ]
[ run where.cpp ]
[ compile-fail where_fail.cpp ]
[ compile-fail usage_fail.cpp ]
# Backward compatibility tests
[ run old_concept_pass.cpp ]
[ compile-fail function_requires_fail.cpp ]
[ compile-fail old_concept_function_fail.cpp ]
[ compile-fail old_concept_class_fail.cpp ]
;

View File

@@ -0,0 +1,34 @@
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/concept_check.hpp>
/*
This file verifies that the BOOST_CLASS_REQUIRE macro of the Boost
Concept Checking Library does not cause errors when it is not suppose
to.
*/
struct foo { bool operator()(int) { return true; } };
struct bar { bool operator()(int, char) { return true; } };
class class_requires_test
{
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<int>));
typedef int* int_ptr; typedef const int* const_int_ptr;
BOOST_CONCEPT_ASSERT((boost::EqualOp<int_ptr,const_int_ptr>));
BOOST_CONCEPT_ASSERT((boost::UnaryFunction<foo,bool,int>));
BOOST_CONCEPT_ASSERT((boost::BinaryFunction<bar,bool,int,char>));
};
int
main()
{
class_requires_test x;
boost::ignore_unused_variable_warning(x);
return 0;
}

View File

@@ -0,0 +1,32 @@
// (C) Copyright Jeremy Siek, David Abrahams 2000-2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Change Log:
// 20 Jan 2001 - Added warning suppression (David Abrahams)
#include <boost/concept_check.hpp>
/*
This file verifies that class_requires of the Boost Concept Checking
Library catches errors when it is supposed to.
*/
struct foo { };
template <class T>
class class_requires_test
{
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<foo>));
};
int
main()
{
class_requires_test<int> x;
(void)x; // suppress unused variable warning
return 0;
}

View File

@@ -0,0 +1,26 @@
// (C) Copyright Jeremy Siek, David Abrahams 2000-2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifdef NDEBUG
# undef NDEBUG
#endif
#include <boost/concept_check.hpp>
/*
This file verifies that BOOST_CONCEPT_ASSERT catches errors in
function context.
*/
struct foo { };
int
main()
{
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<foo>));
return 0;
}

View File

@@ -0,0 +1,177 @@
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
/*
This file verifies that function_requires() of the Boost Concept
Checking Library does not cause errors when it is not suppose to
and verifies that the concept archetypes meet the requirements of
their matching concepts.
*/
int
main()
{
using namespace boost;
//===========================================================================
// Basic Concepts
{
typedef default_constructible_archetype<> foo;
function_requires< DefaultConstructible<foo> >();
}
{
typedef assignable_archetype<> foo;
function_requires< Assignable<foo> >();
}
{
typedef copy_constructible_archetype<> foo;
function_requires< CopyConstructible<foo> >();
}
{
typedef sgi_assignable_archetype<> foo;
function_requires< SGIAssignable<foo> >();
}
{
typedef copy_constructible_archetype<> foo;
typedef convertible_to_archetype<foo> convertible_to_foo;
function_requires< Convertible<convertible_to_foo, foo> >();
}
{
function_requires< Convertible<boolean_archetype, bool> >();
}
{
typedef equality_comparable_archetype<> foo;
function_requires< EqualityComparable<foo> >();
}
{
typedef less_than_comparable_archetype<> foo;
function_requires< LessThanComparable<foo> >();
}
{
typedef comparable_archetype<> foo;
function_requires< Comparable<foo> >();
}
{
typedef equal_op_first_archetype<> First;
typedef equal_op_second_archetype<> Second;
function_requires< EqualOp<First, Second> >();
}
{
typedef not_equal_op_first_archetype<> First;
typedef not_equal_op_second_archetype<> Second;
function_requires< NotEqualOp<First, Second> >();
}
{
typedef less_than_op_first_archetype<> First;
typedef less_than_op_second_archetype<> Second;
function_requires< LessThanOp<First, Second> >();
}
{
typedef less_equal_op_first_archetype<> First;
typedef less_equal_op_second_archetype<> Second;
function_requires< LessEqualOp<First, Second> >();
}
{
typedef greater_than_op_first_archetype<> First;
typedef greater_than_op_second_archetype<> Second;
function_requires< GreaterThanOp<First, Second> >();
}
{
typedef greater_equal_op_first_archetype<> First;
typedef greater_equal_op_second_archetype<> Second;
function_requires< GreaterEqualOp<First, Second> >();
}
{
typedef copy_constructible_archetype<> Return;
typedef plus_op_first_archetype<Return> First;
typedef plus_op_second_archetype<Return> Second;
function_requires< PlusOp<Return, First, Second> >();
}
//===========================================================================
// Function Object Concepts
{
typedef generator_archetype<null_archetype<> > foo;
function_requires< Generator<foo, null_archetype<> > >();
}
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
{
function_requires< Generator< void_generator_archetype, void > >();
}
#endif
{
typedef unary_function_archetype<int, int> F;
function_requires< UnaryFunction<F, int, int> >();
}
{
typedef binary_function_archetype<int, int, int> F;
function_requires< BinaryFunction<F, int, int, int> >();
}
{
typedef unary_predicate_archetype<int> F;
function_requires< UnaryPredicate<F, int> >();
}
{
typedef binary_predicate_archetype<int, int> F;
function_requires< BinaryPredicate<F, int, int> >();
}
//===========================================================================
// Iterator Concepts
{
typedef input_iterator_archetype<null_archetype<> > Iter;
function_requires< InputIterator<Iter> >();
}
{
typedef output_iterator_archetype<int> Iter;
function_requires< OutputIterator<Iter, int> >();
}
{
typedef input_output_iterator_archetype<int> Iter;
function_requires< InputIterator<Iter> >();
function_requires< OutputIterator<Iter, int> >();
}
{
typedef forward_iterator_archetype<null_archetype<> > Iter;
function_requires< ForwardIterator<Iter> >();
}
{
typedef mutable_forward_iterator_archetype<assignable_archetype<> > Iter;
function_requires< Mutable_ForwardIterator<Iter> >();
}
{
typedef bidirectional_iterator_archetype<null_archetype<> > Iter;
function_requires< BidirectionalIterator<Iter> >();
}
{
typedef mutable_bidirectional_iterator_archetype<assignable_archetype<> >
Iter;
function_requires< Mutable_BidirectionalIterator<Iter> >();
}
{
typedef random_access_iterator_archetype<null_archetype<> > Iter;
function_requires< RandomAccessIterator<Iter> >();
}
{
typedef mutable_random_access_iterator_archetype<assignable_archetype<> >
Iter;
function_requires< Mutable_RandomAccessIterator<Iter> >();
}
//===========================================================================
// Container Concepts
// UNDER CONSTRUCTION
return 0;
}

View File

@@ -0,0 +1,27 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP
# define BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP
# include <iterator>
# include <boost/concept/requires.hpp>
# include <boost/concept_check.hpp>
namespace fake
{
using namespace boost;
template<typename RanIter>
BOOST_CONCEPT_REQUIRES(
((Mutable_RandomAccessIterator<RanIter>))
((LessThanComparable<typename Mutable_RandomAccessIterator<RanIter>::value_type>))
, (void))
sort(RanIter,RanIter)
{
}
}
#endif // BOOST_LIBS_CONCEPT_CHECK_FAKE_SORT_DWA2006430_HPP

View File

@@ -0,0 +1,26 @@
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifdef NDEBUG
# undef NDEBUG
#endif
#include <boost/concept_check.hpp>
/*
This file verifies that function_requires() of the Boost Concept
Checking Library catches errors when it is suppose to.
*/
struct foo { };
int
main()
{
boost::function_requires< boost::EqualityComparable<foo> >();
return 0;
}

View File

@@ -0,0 +1,28 @@
// (C) Copyright Jeremy Siek, David Abrahams 2000-2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Change Log:
// 20 Jan 2001 - Added warning suppression (David Abrahams)
#include "old_concepts.hpp"
// This file verifies that concepts written the old way still catch
// errors in class context. This is not expected to work on compilers
// without SFINAE support.
struct foo { };
class class_requires_test
{
BOOST_CLASS_REQUIRE(foo, old, EqualityComparableConcept);
};
int
main()
{
class_requires_test x;
(void)x; // suppress unused variable warning
return 0;
}

View File

@@ -0,0 +1,23 @@
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifdef NDEBUG
# undef NDEBUG
#endif
#include "old_concepts.hpp"
// This file verifies that concepts written the old way still catch
// errors in function context. This is not expected to work on
// compilers without SFINAE support.
struct foo { };
int
main()
{
boost::function_requires< old::EqualityComparableConcept<foo> >();
return 0;
}

View File

@@ -0,0 +1,34 @@
// (C) Copyright Jeremy Siek, David Abrahams 2000-2006.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/concept_check.hpp>
#include "old_concepts.hpp"
// This test verifies that use of the old-style concept checking
// classes still compiles (but not that it detects constraint
// violations). We check them with the old-style macros just for
// completeness, since those macros stranslate into
// BOOST_CONCEPT_ASSERTs.
struct foo { bool operator()(int) { return true; } };
struct bar { bool operator()(int, char) { return true; } };
class class_requires_test
{
BOOST_CLASS_REQUIRE(int, old, EqualityComparableConcept);
typedef int* int_ptr; typedef const int* const_int_ptr;
BOOST_CLASS_REQUIRE2(int_ptr, const_int_ptr, old, EqualOpConcept);
BOOST_CLASS_REQUIRE3(foo, bool, int, old, UnaryFunctionConcept);
BOOST_CLASS_REQUIRE4(bar, bool, int, char, old, BinaryFunctionConcept);
};
int
main()
{
class_requires_test x;
boost::ignore_unused_variable_warning(x);
return 0;
}

View File

@@ -0,0 +1,67 @@
// Copyright Jeremy Siek, David Abrahams 2000-2006. Distributed under
// the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP
# define BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP
#include <boost/concept_check.hpp>
namespace old
{
template <class TT>
void require_boolean_expr(const TT& t) {
bool x = t;
boost::ignore_unused_variable_warning(x);
}
template <class TT>
struct EqualityComparableConcept
{
void constraints() {
boost::require_boolean_expr(a == b);
boost::require_boolean_expr(a != b);
}
TT a, b;
};
template <class Func, class Return, class Arg>
struct UnaryFunctionConcept
{
// required in case any of our template args are const-qualified:
UnaryFunctionConcept();
void constraints() {
r = f(arg); // require operator()
}
Func f;
Arg arg;
Return r;
};
template <class Func, class Return, class First, class Second>
struct BinaryFunctionConcept
{
void constraints() {
r = f(first, second); // require operator()
}
Func f;
First first;
Second second;
Return r;
};
#define DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
template <class First, class Second> \
struct NAME { \
void constraints() { (void)constraints_(); } \
bool constraints_() { \
return a OP b; \
} \
First a; \
Second b; \
}
DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
}
#endif // BOOST_LIBS_CONCEPT_CHECK_OLD_CONCEPTS_DWA2006428_HPP

View File

@@ -0,0 +1,93 @@
// (C) Copyright Jeremy Siek 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// This file checks to see if various standard container
// implementations live up to requirements specified in the C++
// standard. As many implementations do not live to the requirements,
// it is not uncommon for this file to fail to compile. The
// BOOST_HIDE_EXPECTED_ERRORS macro is provided here if you want to
// see as much of this file compile as possible.
//
#include <boost/concept_check.hpp>
#include <iterator>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <deque>
#if 0
#include <slist>
#endif
// Define this macro if you want to hide the expected error, that is,
// error in the various C++ standard library implementations.
//
//#define BOOST_HIDE_EXPECTED_ERRORS
int
main()
{
using namespace boost;
#if defined(_ITERATOR_) && defined(BOOST_HIDE_EXPECTED_ERRORS)
// VC++ STL implementation is not standard conformant and
// fails to pass these concept checks
#else
typedef std::vector<int> Vector;
typedef std::deque<int> Deque;
typedef std::list<int> List;
// VC++ missing pointer and const_pointer typedefs
function_requires< Mutable_RandomAccessContainer<Vector> >();
function_requires< BackInsertionSequence<Vector> >();
#if !(defined(__GNUC__) && defined(BOOST_HIDE_EXPECTED_ERRORS))
#if !((defined(__sgi) || (defined(__DECCXX) && defined(_RWSTD_VER) && _RWSTD_VER <= 0x0203)) \
&& defined(BOOST_HIDE_EXPECTED_ERRORS))
// old deque iterator missing n + iter operation
function_requires< Mutable_RandomAccessContainer<Deque> >();
#endif
// warnings about signed and unsigned in old deque version
function_requires< FrontInsertionSequence<Deque> >();
function_requires< BackInsertionSequence<Deque> >();
#endif
// VC++ missing pointer and const_pointer typedefs
function_requires< Mutable_ReversibleContainer<List> >();
function_requires< FrontInsertionSequence<List> >();
function_requires< BackInsertionSequence<List> >();
#if 0
typedef BOOST_STD_EXTENSION_NAMESPACE::slist<int> SList;
function_requires< FrontInsertionSequence<SList> >();
#endif
typedef std::set<int> Set;
typedef std::multiset<int> MultiSet;
typedef std::map<int,int> Map;
typedef std::multimap<int,int> MultiMap;
function_requires< SortedAssociativeContainer<Set> >();
function_requires< SimpleAssociativeContainer<Set> >();
function_requires< UniqueAssociativeContainer<Set> >();
function_requires< SortedAssociativeContainer<MultiSet> >();
function_requires< SimpleAssociativeContainer<MultiSet> >();
function_requires< MultipleAssociativeContainer<MultiSet> >();
function_requires< SortedAssociativeContainer<Map> >();
function_requires< UniqueAssociativeContainer<Map> >();
function_requires< PairAssociativeContainer<Map> >();
function_requires< SortedAssociativeContainer<MultiMap> >();
function_requires< MultipleAssociativeContainer<MultiMap> >();
function_requires< PairAssociativeContainer<MultiMap> >();
#endif
return 0;
}

View File

@@ -0,0 +1,950 @@
// (C) Copyright Jeremy Siek 2000-2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <algorithm>
#include <numeric>
#include <boost/config.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
/*
This file uses the archetype classes to find out which concepts
actually *cover* the STL algorithms true requirements. The
archetypes/concepts chosen do not necessarily match the C++ standard
or the SGI STL documentation, but instead were chosen based on the
minimal concepts that current STL implementations require, which in
many cases is less stringent than the standard. In some places there
was significant differences in the implementations' requirements and
in those places macros were used to select different requirements,
the purpose being to document what the requirements of various
implementations are. It is an open issue as to whether the C++
standard should be changed to reflect these weaker requirements.
*/
/**
* Input iterator - explanation from Peter Dimov:
*
* Requirements say that *it is convertible to the value_type, and it is, in
* our case. The problem however is that op== is a template and the first
* argument fails deduction. std::find is specified in terms of the exact
* expression `*it == value`, so if it doesn't compile (and it doesn't),
* `find(it, it, value)` won't compile either.
*
* To address this, the no_proxy variant of the input iterator is used
* instead.
*/
#define BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE input_iterator_archetype_no_proxy
boost::detail::dummy_constructor dummy_cons;
// This is a special concept needed for std::swap_ranges.
// It is mutually convertible, and also SGIAssignable
template <class T>
class mutually_convertible_archetype
{
private:
mutually_convertible_archetype() { }
public:
mutually_convertible_archetype(const mutually_convertible_archetype&) { }
mutually_convertible_archetype&
operator=(const mutually_convertible_archetype&)
{ return *this; }
mutually_convertible_archetype(boost::detail::dummy_constructor) { }
template <class U>
mutually_convertible_archetype&
operator=(const mutually_convertible_archetype<U>&)
{ return *this; }
};
// for std::accumulate
namespace accum
{
typedef boost::sgi_assignable_archetype<> Ret;
struct T {
T(const Ret&) { }
T(boost::detail::dummy_constructor x) { }
};
typedef boost::null_archetype<> Tin;
Ret operator+(const T&, const Tin&) {
return Ret(dummy_cons);
}
}
// for std::shuffle
namespace shuffle
{
struct URBG {
typedef unsigned int result_type;
result_type BOOST_CONSTEXPR static min() { return 0; }
result_type BOOST_CONSTEXPR static max() { return 1; }
result_type operator()() { return 1; }
};
}
// for std::inner_product
namespace inner_prod
{
typedef boost::sgi_assignable_archetype<> RetAdd;
typedef boost::sgi_assignable_archetype<> RetMult;
struct T {
T(const RetAdd&) { }
T(boost::detail::dummy_constructor x) { }
};
typedef boost::null_archetype<int> Tin1;
typedef boost::null_archetype<char> Tin2;
}
namespace boost { // so Koenig lookup will find
inner_prod::RetMult
operator*(const inner_prod::Tin1&, const inner_prod::Tin2&) {
return inner_prod::RetMult(dummy_cons);
}
inner_prod::RetAdd
operator+(const inner_prod::T&,
const inner_prod::RetMult&) {
return inner_prod::RetAdd(dummy_cons);
}
}
// for std::partial_sum and adj_diff
namespace part_sum
{
class T {
public:
typedef boost::sgi_assignable_archetype<> Ret;
T(const Ret&) { }
T(boost::detail::dummy_constructor x) { }
private:
T() { }
};
T::Ret operator+(const T&, const T&) {
return T::Ret(dummy_cons);
}
T::Ret operator-(const T&, const T&) {
return T::Ret(dummy_cons);
}
}
// for std::power
namespace power_stuff {
struct monoid_archetype {
monoid_archetype(boost::detail::dummy_constructor x) { }
};
boost::multipliable_archetype<monoid_archetype>
identity_element
(std::multiplies< boost::multipliable_archetype<monoid_archetype> >)
{
return boost::multipliable_archetype<monoid_archetype>(dummy_cons);
}
}
struct tag1 { };
struct tag2 { };
int
main()
{
using namespace boost;
//===========================================================================
// Non-mutating Algorithms
{
input_iterator_archetype< null_archetype<> > in;
unary_function_archetype< null_archetype<> , null_archetype<> >
f(dummy_cons);
std::for_each(in, in, f);
}
// gcc bug
{
typedef equality_comparable2_first_archetype<> Left;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE< Left > in;
equality_comparable2_second_archetype<> value(dummy_cons);
in = std::find(in, in, value);
}
{
typedef null_archetype<> T;
input_iterator_archetype<T> in;
unary_predicate_archetype<T> pred(dummy_cons);
in = std::find_if(in, in, pred);
}
{
forward_iterator_archetype< equality_comparable_archetype<> > fo;
fo = std::adjacent_find(fo, fo);
}
{
forward_iterator_archetype<
convertible_to_archetype< null_archetype<> > > fo;
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
fo = std::adjacent_find(fo, fo, pred);
}
// gcc bug
{
typedef equal_op_first_archetype<> Left;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> in;
typedef equal_op_second_archetype<> Right;
forward_iterator_archetype<Right> fo;
in = std::find_first_of(in, in, fo, fo);
}
{
typedef equal_op_first_archetype<> Left;
typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> InIter;
InIter in;
function_requires< InputIterator<InIter> >();
equal_op_second_archetype<> value(dummy_cons);
std::iterator_traits<InIter>::difference_type
n = std::count(in, in, value);
ignore_unused_variable_warning(n);
}
{
typedef input_iterator_archetype< null_archetype<> > InIter;
InIter in;
unary_predicate_archetype<null_archetype<> > pred(dummy_cons);
std::iterator_traits<InIter>::difference_type
n = std::count_if(in, in, pred);
ignore_unused_variable_warning(n);
}
// gcc bug
{
typedef equal_op_first_archetype<> Left;
typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> InIter1;
InIter1 in1;
typedef equal_op_second_archetype<> Right;
typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Right> InIter2;
InIter2 in2;
std::pair<InIter1, InIter2> p = std::mismatch(in1, in1, in2);
ignore_unused_variable_warning(p);
}
{
typedef input_iterator_archetype<null_archetype<> > InIter;
InIter in1, in2;
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
std::pair<InIter, InIter> p = std::mismatch(in1, in1, in2, pred);
ignore_unused_variable_warning(p);
}
// gcc bug
{
typedef equality_comparable2_first_archetype<> Left;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> in1;
typedef equality_comparable2_second_archetype<> Right;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Right> in2;
bool b = std::equal(in1, in1, in2);
ignore_unused_variable_warning(b);
}
{
input_iterator_archetype< null_archetype<> >
in1, in2;
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
bool b = std::equal(in1, in1, in2, pred);
ignore_unused_variable_warning(b);
}
{
typedef equality_comparable2_first_archetype<> Left;
forward_iterator_archetype<Left> fo1;
typedef equality_comparable2_second_archetype<> Right;
forward_iterator_archetype<Right> fo2;
fo1 = std::search(fo1, fo1, fo2, fo2);
}
{
typedef equality_comparable2_first_archetype<
convertible_to_archetype<null_archetype<> > > Left;
forward_iterator_archetype<Left> fo1;
typedef equality_comparable2_second_archetype<
convertible_to_archetype<null_archetype<> > > Right;
forward_iterator_archetype<Right> fo2;
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
fo1 = std::search(fo1, fo1, fo2, fo2, pred);
}
{
typedef equality_comparable2_first_archetype<> Left;
forward_iterator_archetype<Left> fo;
equality_comparable2_second_archetype<> value(dummy_cons);
int n = 1;
fo = std::search_n(fo, fo, n, value);
}
{
forward_iterator_archetype<
convertible_to_archetype<null_archetype<> > > fo;
convertible_to_archetype<null_archetype<> > value(dummy_cons);
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
int n = 1;
fo = std::search_n(fo, fo, n, value, pred);
}
{
typedef equality_comparable2_first_archetype<> Left;
forward_iterator_archetype<Left> fo1;
typedef equality_comparable2_second_archetype<null_archetype<> > Right;
forward_iterator_archetype<Right> fo2;
fo1 = std::find_end(fo1, fo1, fo2, fo2);
}
{
// equality comparable required because find_end() calls search
typedef equality_comparable2_first_archetype<
convertible_to_archetype<null_archetype<> > > Left;
forward_iterator_archetype<Left> fo1;
typedef equality_comparable2_second_archetype<
convertible_to_archetype<null_archetype<> > > Right;
forward_iterator_archetype<Right> fo2;
binary_predicate_archetype<null_archetype<> , null_archetype<> >
pred(dummy_cons);
fo1 = std::find_end(fo1, fo1, fo2, fo2, pred);
}
//===========================================================================
// Mutating Algorithms
{
typedef null_archetype<> T;
input_iterator_archetype<T> in;
output_iterator_archetype<T> out(dummy_cons);
out = std::copy(in, in, out);
}
{
typedef assignable_archetype<> OutT;
typedef convertible_to_archetype<OutT> InT;
bidirectional_iterator_archetype<InT> bid_in;
mutable_bidirectional_iterator_archetype<OutT> bid_out;
bid_out = std::copy_backward(bid_in, bid_in, bid_out);
}
{
sgi_assignable_archetype<> a(dummy_cons), b(dummy_cons);
std::swap(a, b);
}
{
typedef sgi_assignable_archetype<> T;
mutable_forward_iterator_archetype<T> a, b;
std::iter_swap(a, b);
}
#if 0
{
// fails on gcc 7.3 and clang 6.0
typedef mutually_convertible_archetype<int> Tin;
typedef mutually_convertible_archetype<char> Tout;
mutable_forward_iterator_archetype<Tin> fi1;
mutable_forward_iterator_archetype<Tout> fi2;
fi2 = std::swap_ranges(fi1, fi1, fi2);
}
#endif
{
typedef null_archetype<int> Tin;
typedef null_archetype<char> Tout;
input_iterator_archetype<Tin> in;
output_iterator_archetype<Tout> out(dummy_cons);
unary_function_archetype<null_archetype<> ,
convertible_to_archetype<Tout> > op(dummy_cons);
out = std::transform(in, in, out, op);
}
{
typedef null_archetype<int> Tin1;
typedef null_archetype<char> Tin2;
typedef null_archetype<double> Tout;
input_iterator_archetype<Tin1> in1;
input_iterator_archetype<Tin2> in2;
output_iterator_archetype<Tout> out(dummy_cons);
binary_function_archetype<Tin1, Tin2,
convertible_to_archetype<Tout> > op(dummy_cons);
out = std::transform(in1, in1, in2, out, op);
}
{
typedef equality_comparable2_first_archetype<
assignable_archetype<> > FT;
mutable_forward_iterator_archetype<FT> fi;
equality_comparable2_second_archetype<
convertible_to_archetype<FT> > value(dummy_cons);
std::replace(fi, fi, value, value);
}
{
typedef null_archetype<> PredArg;
typedef assignable_archetype<
convertible_to_archetype<PredArg> > FT;
mutable_forward_iterator_archetype<FT> fi;
unary_predicate_archetype<PredArg> pred(dummy_cons);
convertible_to_archetype<FT> value(dummy_cons);
std::replace_if(fi, fi, pred, value);
}
#if (!defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, > 1900)) && !defined(BOOST_EMBTC)
// fails on MSVC 2015 and earlier
{
// Issue, the use of ?: inside replace_copy() complicates things
typedef equal_op_first_archetype<> Tin;
typedef null_archetype<> Tout;
typedef equal_op_second_archetype< convertible_to_archetype<Tout> > T;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
output_iterator_archetype<Tout> out(dummy_cons);
T value(dummy_cons);
out = std::replace_copy(in, in, out, value, value);
}
{
// The issue of ?: also affects this function
typedef null_archetype<> Tout;
typedef assignable_archetype< convertible_to_archetype<Tout> > Tin;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
output_iterator_archetype<Tout> out(dummy_cons);
unary_predicate_archetype<Tin> pred(dummy_cons);
Tin value(dummy_cons);
out = std::replace_copy_if(in, in, out, pred, value);
}
#endif
{
typedef assignable_archetype<> FT;
mutable_forward_iterator_archetype<FT> fi;
typedef convertible_to_archetype<FT> T;
T value(dummy_cons);
std::fill(fi, fi, value);
}
#if !defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, >= 1700)
// fails on MSVC 2010
{
typedef null_archetype<> Tout;
typedef convertible_to_archetype<Tout> T;
output_iterator_archetype<Tout> out(dummy_cons);
T value(dummy_cons);
int n = 1;
out = std::fill_n(out, n, value);
}
#endif
{
typedef assignable_archetype<> FT;
typedef convertible_to_archetype<FT> Ret;
mutable_forward_iterator_archetype<FT> fi;
generator_archetype<Ret> gen;
std::generate(fi, fi, gen);
}
{
typedef assignable_archetype<> FT;
typedef convertible_to_archetype<FT> Ret;
mutable_forward_iterator_archetype<FT> fi;
generator_archetype<Ret> gen;
int n = 1;
std::generate_n(fi, n, gen);
}
{
typedef assignable_archetype< equality_comparable2_first_archetype<> > FT;
typedef equality_comparable2_second_archetype<> T;
mutable_forward_iterator_archetype<FT> fi;
T value(dummy_cons);
fi = std::remove(fi, fi, value);
}
{
typedef assignable_archetype<> FT;
mutable_forward_iterator_archetype<FT> fi;
typedef null_archetype<> PredArg;
unary_predicate_archetype<PredArg> pred(dummy_cons);
fi = std::remove_if(fi, fi, pred);
}
// gcc bug
{
typedef null_archetype<> Tout;
typedef equality_comparable2_first_archetype<
convertible_to_archetype<Tout> > Tin;
typedef equality_comparable2_second_archetype<> T;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
output_iterator_archetype<Tout> out(dummy_cons);
T value(dummy_cons);
out = std::remove_copy(in, in, out, value);
}
{
typedef null_archetype<> T;
input_iterator_archetype<T> in;
output_iterator_archetype<T> out(dummy_cons);
unary_predicate_archetype<T> pred(dummy_cons);
out = std::remove_copy_if(in, in, out, pred);
}
{
typedef sgi_assignable_archetype< equality_comparable_archetype<> > T;
mutable_forward_iterator_archetype<T> fi;
fi = std::unique(fi, fi);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg1,
convertible_to_archetype<Arg2> > > FT;
mutable_forward_iterator_archetype<FT> fi;
binary_predicate_archetype<Arg1, Arg2> pred(dummy_cons);
fi = std::unique(fi, fi, pred);
}
// gcc bug
{
typedef equality_comparable_archetype< sgi_assignable_archetype<> > T;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<T> in;
output_iterator_archetype<T> out(dummy_cons);
out = std::unique_copy(in, in, out);
}
{
typedef sgi_assignable_archetype<> T;
input_iterator_archetype<T> in;
output_iterator_archetype<T> out(dummy_cons);
binary_predicate_archetype<T, T> pred(dummy_cons);
out = std::unique_copy(in, in, out, pred);
}
{
typedef sgi_assignable_archetype<> T;
mutable_bidirectional_iterator_archetype<T> bi;
std::reverse(bi, bi);
}
{
typedef null_archetype<> Tout;
typedef convertible_to_archetype<Tout> Tin;
bidirectional_iterator_archetype<Tin> bi;
output_iterator_archetype<Tout> out(dummy_cons);
out = std::reverse_copy(bi, bi, out);
}
{
typedef sgi_assignable_archetype<> T;
mutable_forward_iterator_archetype<T> fi;
// Issue, SGI STL is not have void return type, C++ standard does
std::rotate(fi, fi, fi);
}
{
typedef null_archetype<> Tout;
typedef convertible_to_archetype<Tout> FT;
forward_iterator_archetype<FT> fi;
output_iterator_archetype<Tout> out(dummy_cons);
out = std::rotate_copy(fi, fi, fi, out);
}
#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE
{
typedef sgi_assignable_archetype<> T;
mutable_random_access_iterator_archetype<T> ri;
std::random_shuffle(ri, ri);
}
{
typedef sgi_assignable_archetype<> T;
mutable_random_access_iterator_archetype<T> ri;
unary_function_archetype<std::ptrdiff_t, std::ptrdiff_t> ran(dummy_cons);
std::random_shuffle(ri, ri, ran);
}
#else
{
typedef sgi_assignable_archetype<> T;
mutable_random_access_iterator_archetype<T> ri;
shuffle::URBG urbg;
std::shuffle(ri, ri, urbg);
}
#endif
{
typedef null_archetype<> PredArg;
typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
mutable_bidirectional_iterator_archetype<FT> bi;
unary_predicate_archetype<PredArg> pred(dummy_cons);
bi = std::partition(bi, bi, pred);
}
#if !defined(BOOST_MSVC) && !defined(BOOST_EMBTC)
{
// fails on MSVC
typedef null_archetype<> PredArg;
typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
mutable_forward_iterator_archetype<FT> fi;
unary_predicate_archetype<PredArg> pred(dummy_cons);
fi = std::stable_partition(fi, fi, pred);
}
#endif
//===========================================================================
// Sorting Algorithms
{
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
mutable_random_access_iterator_archetype<T> ri;
std::sort(ri, ri);
}
{
typedef null_archetype<> Arg;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > T;
mutable_random_access_iterator_archetype<T> ri;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
std::sort(ri, ri, comp);
}
{
typedef less_than_comparable_archetype<
sgi_assignable_archetype<> > ValueType;
mutable_random_access_iterator_archetype<ValueType> ri;
std::stable_sort(ri, ri);
}
{
typedef null_archetype<> Arg;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > ValueType;
mutable_random_access_iterator_archetype<ValueType> ri;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
std::stable_sort(ri, ri, comp);
}
{
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
mutable_random_access_iterator_archetype<T> ri;
std::partial_sort(ri, ri, ri);
}
{
typedef null_archetype<> Arg;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > T;
mutable_random_access_iterator_archetype<T> ri;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
std::partial_sort(ri, ri, ri, comp);
}
// gcc bug
{
// This could be formulated so that the two iterators are not
// required to have the same value type, but it is messy.
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<T> in;
mutable_random_access_iterator_archetype<T> ri_out;
ri_out = std::partial_sort_copy(in, in , ri_out, ri_out);
}
{
typedef sgi_assignable_archetype<> T;
input_iterator_archetype<T> in;
mutable_random_access_iterator_archetype<T> ri_out;
binary_predicate_archetype<T, T> comp(dummy_cons);
ri_out = std::partial_sort_copy(in, in , ri_out, ri_out, comp);
}
{
typedef sgi_assignable_archetype< less_than_comparable_archetype<> > T;
mutable_random_access_iterator_archetype<T> ri;
std::nth_element(ri, ri, ri);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg1,
convertible_to_archetype<Arg2> > > T;
mutable_random_access_iterator_archetype<T> ri;
binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
std::nth_element(ri, ri, ri, comp);
}
{
#if defined(__KCC)
// The KAI version of this uses a one-argument less-than function
// object.
typedef less_than_comparable_archetype<> T;
typedef convertible_to_archetype<T> FT;
#else
typedef less_than_op_first_archetype<> FT;
typedef less_than_op_second_archetype<> T;
#endif
forward_iterator_archetype<FT> fi;
T value(dummy_cons);
fi = std::lower_bound(fi, fi, value);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef convertible_to_archetype<Arg1> FT;
typedef convertible_to_archetype<Arg2> T;
forward_iterator_archetype<FT> fi;
T value(dummy_cons);
binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
fi = std::lower_bound(fi, fi, value, comp);
}
{
#if defined(__KCC)
typedef less_than_comparable_archetype<> T;
typedef convertible_to_archetype<T> FT;
#else
// Note, order of T,FT is flipped from lower_bound
typedef less_than_op_second_archetype<> FT;
typedef less_than_op_first_archetype<> T;
#endif
forward_iterator_archetype<FT> fi;
T value(dummy_cons);
fi = std::upper_bound(fi, fi, value);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
// Note, order of T,FT is flipped from lower_bound
typedef convertible_to_archetype<Arg1> T;
typedef convertible_to_archetype<Arg2> FT;
forward_iterator_archetype<FT> fi;
T value(dummy_cons);
binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
fi = std::upper_bound(fi, fi, value, comp);
}
#if !defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, >= 1900)
// Fails on MSVC 2013 and earlier
{
#if defined(__KCC)
typedef less_than_comparable_archetype<> T;
typedef convertible_to_archetype<T> FT;
#else
typedef less_than_op_first_archetype<
less_than_op_second_archetype< null_archetype<>, optag2>, optag1> FT;
typedef less_than_op_second_archetype<
less_than_op_first_archetype< null_archetype<>, optag2>, optag1> T;
#endif
typedef forward_iterator_archetype<FT> FIter;
FIter fi;
T value(dummy_cons);
std::pair<FIter,FIter> p = std::equal_range(fi, fi, value);
ignore_unused_variable_warning(p);
}
#endif
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef convertible_to_archetype<Arg1,
convertible_to_archetype<Arg2> > FT;
typedef convertible_to_archetype<Arg2,
convertible_to_archetype<Arg1> > T;
typedef forward_iterator_archetype<FT> FIter;
FIter fi;
T value(dummy_cons);
binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
std::pair<FIter,FIter> p = std::equal_range(fi, fi, value, comp);
ignore_unused_variable_warning(p);
}
{
#if defined(__KCC)
typedef less_than_op_first_archetype< less_than_comparable_archetype<> > T;
typedef less_than_op_second_archetype< convertible_to_archetype<T> > FT;
#else
typedef less_than_op_first_archetype<
less_than_op_second_archetype<null_archetype<>, optag2>, optag1> FT;
typedef less_than_op_second_archetype<
less_than_op_first_archetype<null_archetype<>, optag2>, optag1> T;
#endif
forward_iterator_archetype<FT> fi;
T value(dummy_cons);
bool b = std::binary_search(fi, fi, value);
ignore_unused_variable_warning(b);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef convertible_to_archetype<Arg1,
convertible_to_archetype<Arg2> > FT;
typedef convertible_to_archetype<Arg2,
convertible_to_archetype<Arg1> > T;
typedef forward_iterator_archetype<FT> FIter;
FIter fi;
T value(dummy_cons);
binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
bool b = std::binary_search(fi, fi, value, comp);
ignore_unused_variable_warning(b);
}
{
typedef null_archetype<> Tout;
typedef less_than_op_first_archetype<
less_than_op_second_archetype<
convertible_to_archetype<Tout>, optag2>, optag1 > Tin1;
typedef less_than_op_second_archetype<
less_than_op_first_archetype<
convertible_to_archetype<Tout>, optag2> ,optag1> Tin2;
// gcc bug
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin1> in1;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin2> in2;
output_iterator_archetype<Tout> out(dummy_cons);
out = std::merge(in1, in1, in2, in2, out);
out = std::set_union(in1, in1, in2, in2, out);
out = std::set_intersection(in1, in1, in2, in2, out);
out = std::set_difference(in1, in1, in2, in2, out);
out = std::set_symmetric_difference(in1, in1, in2, in2, out);
}
{
typedef null_archetype<> T;
input_iterator_archetype<T> in1;
input_iterator_archetype<T,2> in2;
output_iterator_archetype<T> out(dummy_cons);
binary_predicate_archetype<T, T> comp(dummy_cons);
out = std::merge(in1, in1, in2, in2, out, comp);
out = std::set_union(in1, in1, in2, in2, out, comp);
out = std::set_intersection(in1, in1, in2, in2, out, comp);
out = std::set_difference(in1, in1, in2, in2, out, comp);
out = std::set_symmetric_difference(in1, in1, in2, in2, out, comp);
}
{
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
mutable_bidirectional_iterator_archetype<T> bi;
std::inplace_merge(bi, bi, bi);
}
{
typedef null_archetype<> Arg;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > T;
mutable_bidirectional_iterator_archetype<T> bi;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
std::inplace_merge(bi, bi, bi, comp);
}
// gcc bug
{
typedef less_than_op_first_archetype<
less_than_op_second_archetype<null_archetype<>, optag1>, optag2> Tin1;
typedef less_than_op_second_archetype<
less_than_op_first_archetype<null_archetype<>, optag1>, optag2> Tin2;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin1> in1;
BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin2> in2;
bool b = std::includes(in1, in1, in2, in2);
b = std::lexicographical_compare(in1, in1, in2, in2);
ignore_unused_variable_warning(b);
}
{
typedef null_archetype<int> Tin;
input_iterator_archetype<Tin> in1;
input_iterator_archetype<Tin,1> in2;
binary_predicate_archetype<Tin, Tin> comp(dummy_cons);
bool b = std::includes(in1, in1, in2, in2, comp);
b = std::lexicographical_compare(in1, in1, in2, in2, comp);
ignore_unused_variable_warning(b);
}
{
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
mutable_random_access_iterator_archetype<T> ri;
std::push_heap(ri, ri);
std::pop_heap(ri, ri);
std::make_heap(ri, ri);
std::sort_heap(ri, ri);
}
{
typedef null_archetype<> Arg;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > T;
mutable_random_access_iterator_archetype<T> ri;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
std::push_heap(ri, ri, comp);
std::pop_heap(ri, ri, comp);
std::make_heap(ri, ri, comp);
std::sort_heap(ri, ri, comp);
}
{
typedef less_than_comparable_archetype<> T;
T a(dummy_cons), b(dummy_cons);
BOOST_USING_STD_MIN();
BOOST_USING_STD_MAX();
const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
ignore_unused_variable_warning(c);
ignore_unused_variable_warning(d);
}
{
typedef null_archetype<> Arg;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
typedef convertible_to_archetype<Arg> T;
T a(dummy_cons), b(dummy_cons);
BOOST_USING_STD_MIN();
BOOST_USING_STD_MAX();
const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
ignore_unused_variable_warning(c);
ignore_unused_variable_warning(d);
}
{
typedef less_than_comparable_archetype<> T;
forward_iterator_archetype<T> fi;
fi = std::min_element(fi, fi);
fi = std::max_element(fi, fi);
}
{
typedef null_archetype<> Arg;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
typedef convertible_to_archetype<Arg> T;
forward_iterator_archetype<T> fi;
fi = std::min_element(fi, fi, comp);
fi = std::max_element(fi, fi, comp);
}
{
typedef sgi_assignable_archetype<
less_than_comparable_archetype<> > T;
mutable_bidirectional_iterator_archetype<T> bi;
bool b = std::next_permutation(bi, bi);
b = std::prev_permutation(bi, bi);
ignore_unused_variable_warning(b);
}
{
typedef null_archetype<> Arg;
binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg> > T;
mutable_bidirectional_iterator_archetype<T> bi;
bool b = std::next_permutation(bi, bi, comp);
b = std::prev_permutation(bi, bi, comp);
ignore_unused_variable_warning(b);
}
//===========================================================================
// Generalized Numeric Algorithms
{
// Bummer, couldn't use plus_op because of a problem with
// mutually recursive types.
input_iterator_archetype<accum::Tin> in;
accum::T init(dummy_cons);
init = std::accumulate(in, in, init);
}
{
typedef null_archetype<int> Arg1;
typedef null_archetype<char> Arg2;
typedef sgi_assignable_archetype<
convertible_to_archetype<Arg1> > T;
typedef convertible_to_archetype<T> Ret;
input_iterator_archetype<Arg2> in;
T init(dummy_cons);
binary_function_archetype<Arg1, Arg2, Ret> op(dummy_cons);
init = std::accumulate(in, in, init, op);
}
{
input_iterator_archetype<inner_prod::Tin1> in1;
input_iterator_archetype<inner_prod::Tin2> in2;
inner_prod::T init(dummy_cons);
init = std::inner_product(in1, in1, in2, init);
}
{
typedef null_archetype<int> MultArg1;
typedef null_archetype<char> MultArg2;
typedef null_archetype<short> AddArg1;
typedef null_archetype<long> AddArg2;
typedef sgi_assignable_archetype<
convertible_to_archetype<AddArg1> > T;
typedef convertible_to_archetype<AddArg2> RetMult;
typedef convertible_to_archetype<T> RetAdd;
input_iterator_archetype<MultArg1> in1;
input_iterator_archetype<MultArg2> in2;
T init(dummy_cons);
binary_function_archetype<MultArg1, MultArg2, RetMult> mult_op(dummy_cons);
binary_function_archetype<AddArg1, AddArg2, RetAdd> add_op(dummy_cons);
init = std::inner_product(in1, in1, in2, init, add_op, mult_op);
}
{
input_iterator_archetype<part_sum::T> in;
output_iterator_archetype<part_sum::T> out(dummy_cons);
out = std::partial_sum(in, in, out);
}
{
typedef sgi_assignable_archetype<> T;
input_iterator_archetype<T> in;
output_iterator_archetype<T> out(dummy_cons);
binary_function_archetype<T, T, T> add_op(dummy_cons);
out = std::partial_sum(in, in, out, add_op);
binary_function_archetype<T, T, T> subtract_op(dummy_cons);
out = std::adjacent_difference(in, in, out, subtract_op);
}
{
input_iterator_archetype<part_sum::T> in;
output_iterator_archetype<part_sum::T> out(dummy_cons);
out = std::adjacent_difference(in, in, out);
}
return 0;
}

View File

@@ -0,0 +1,24 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/concept/usage.hpp>
#include <boost/core/ignore_unused.hpp>
template <class T>
struct StringInitializable
{
typedef int associated;
BOOST_CONCEPT_USAGE(StringInitializable)
{
T x = "foo";
boost::ignore_unused(x);
}
};
// Test that accessing an associated type will actually exercise usage
// requirements
typedef StringInitializable<int>::associated tee;

View File

@@ -0,0 +1,13 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
#undef NDEBUG
#include "fake_sort.hpp"
int main()
{
std::vector<int> v;
fake::sort(v.begin(), v.end());
return 0;
}

View File

@@ -0,0 +1,13 @@
// Copyright David Abrahams 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <list>
#undef NDEBUG
#include "fake_sort.hpp"
int main()
{
std::list<int> v;
fake::sort(v.begin(), v.end());
return 0;
}

View File

@@ -0,0 +1,186 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 -->
<!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<title>Using Concept Checks</title>
<link rel="stylesheet" href="../../rst.css" type="text/css" />
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86" /><br clear="none" />
<h2><a name="using-concept-checks" id="using-concept-checks">Using Concept
Checks</a></h2>
<p>For each concept there is a concept checking class template that can be
used to make sure that a given type (or set of types) models the concept.
The Boost Concept Checking Library (BCCL) includes concept checking class
templates for all of the concepts used in the C++ standard library and a
few more. See the <a href="./reference.htm">Reference</a> section for a
complete list. In addition, other boost libraries come with concept
checking classes for the concepts that are particular to those libraries.
For example, there are <a href="../graph/doc/graph_concepts.html">graph
concepts</a> and <a href="../property_map/doc/property_map.html">property map
concepts</a>. Also, whenever <b>anyone</b> writing function templates needs
to express requirements that are not yet stated by an existing concept, a
new concept checking class should be created. How to do this is explained
in <a href="./creating_concepts.htm">Creating Concept Checking
Classes</a>.</p>
<p>An example of a concept checking class from the BCCL is the
<tt>EqualityComparableConcept</tt> class. The class corresponds to the
EqualityComparable requirements described in 20.1.1 of the C++ Standard,
and to the <a href=
"http://www.boost.org/sgi/stl/EqualityComparable.html">EqualityComparable</a>
concept documented in the SGI STL.</p>
<pre>
template &lt;class T&gt;
struct EqualityComparable;
</pre>
<p>The template argument is the type to be checked. That is, the purpose of
<tt>EqualityComparable&lt;<em>T</em>&gt;</tt> is to make sure that
<tt><em>T</em></tt> models the EqualityComparable concept.</p>
<h4><tt>BOOST_CONCEPT_ASSERT()</tt></h4>
<p>The most versatile way of checking concept requirements is to use the
<code>BOOST_CONCEPT_ASSERT()</code> macro. You can use this macro at any
scope, by passing a concept checking template specialization enclosed in
parentheses. <strong>Note:</strong> that means invocations of
<code>BOOST_CONCEPT_ASSERT</code> will appear to use <strong>double
parentheses</strong>.</p>
<pre>
<font color="green">// In my library:</font>
template &lt;class T&gt;
void generic_library_function(T x)
{
BOOST_CONCEPT_ASSERT<strong>((</strong>EqualityComparable&lt;T&gt;<strong>))</strong>;
<font color="green">// ...</font>
};
template &lt;class It&gt;
class generic_library_class
{
BOOST_CONCEPT_ASSERT<strong>((</strong>RandomAccessIterator&lt;It&gt;<strong>))</strong>;
<font color="green">// ...</font>
};
<font color="green">// In the user's code:</font>
class foo {
<font color="green">//... </font>
};
int main() {
foo x;
generic_library_function(x);
generic_library_class&lt;std::vector&lt;char&gt;::iterator&gt; y;
<font color="green">//...</font>
}
</pre>
<h4><tt>BOOST_CONCEPT_REQUIRES</tt></h4>
<p>One of the nice things about the proposed C++0x <a href=
"http://www.generic-programming.org/languages/conceptcpp/tutorial">syntax
for declaring concept constrained function templates</a> is the way that
constraints are part of the function <em>declaration</em>, so clients will
see them. <code>BOOST_CONCEPT_ASSERT</code> can only express constraints
within the function template definition, which hides the constraint in the
function body. Aside from the loss of a self-documenting interface,
asserting conformance only in the function body can undesirably delay
checking if the function is explicitly instantiated in a different
translation unit from the one in which it is called, or if the compiler
does link-time instantiation.</p>
<p>The <tt>BOOST_CONCEPT_REQUIRES</tt> macro can be used in a function
template declaration to check whether some type models a concept. It
accepts two arguments, a <strong>list of constraints</strong>, and the
function template's return type. The list of constraints takes the form of
a sequence of adjacent concept checking template specializations,
<strong>in double parentheses</strong>, and the function's return type must
also be parenthesized. For example, the standard <code>stable_sort</code>
algorithm might be declared as follows: </p>
<pre>
template &lt;class RanIter&gt;
BOOST_CONCEPT_REQUIRES(
((Mutable_RandomAccessIterator&lt;RanIter&gt;))
((LessThanComparable&lt;typename Mutable_RandomAccessIterator&lt;RanIter&gt;::value_type&gt;)),
(void)) <font color="green">// return type</font>
stable_sort(RanIter,RanIter);
</pre>
<p>Note that the algorithm requires that the value type of the iterator be
LessThanComparable, and it accesses that value type through the
<code>Mutable_RandomAccessIterator</code> concept checking template. In
general, the Boost concept checking classes expose associated types as
nested member typedefs so that you can use this syntax, which mimics the
approach used in the concept support proposed for the next version of
C++.</p>
<h4>Multi-Type Concepts</h4>
<p>Some concepts deal with more than one type. In this case the
corresponding concept checking class will have multiple template
parameters. The following example shows how <tt>BOOST_CONCEPT_REQUIRES</tt>
is used with the <a href=
"../property_map/doc/ReadWritePropertyMap.html">ReadWritePropertyMap</a>
concept, which takes two type parameters: a property map and the key type
for the map.</p>
<pre>
template &lt;class G, class Buffer, class BFSVisitor,
class ColorMap&gt;
BOOST_CONCEPT_REQUIRES(
((ReadWritePropertyMap&lt;ColorMap, typename IncidenceGraph&lt;G&gt;::vertex_descriptor&gt;)),
(void)) <font color="green">// return type</font>
breadth_first_search(G&amp; g,
typename graph_traits&lt;IncidenceGraph&gt;::vertex_descriptor s,
Buffer&amp; Q, BFSVisitor vis, ColorMap color)
{
typedef typename IncidenceGraph&lt;G&gt;::vertex_descriptor Vertex;
...
}
</pre>
<p>Although concept checks are designed for use by generic library
implementors, they can also be useful to end users. Sometimes one may not
be sure whether some type models a particular concept. The syntactic
requirements, at least, can easily be checked by creating a small program
and using <tt>BOOST_CONCEPT_ASSERT</tt> with the type and concept in
question. For example:</p>
<pre>
<font color=
"green">// Make sure list&lt;int&gt; has bidirectional iterators.</font>
BOOST_CONCEPT_ASSERT((BidirectionalIterator&lt;std::list&lt;int&gt;::iterator&gt;));
</pre>
<p><a href="./concept_check.htm">Prev: Concept Checking
Introduction</a><br />
<a href="./creating_concepts.htm">Next: Creating Concept Checking
Classes</a><br /></p>
<hr />
<table>
<tr valign="top">
<td nowrap="nowrap">Copyright &copy; 2000</td>
<td><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>(<a href=
"mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>) Andrew
Lumsdaine(<a href="mailto:lums@osl.iu.edu">lums@osl.iu.edu</a>), 2007
<a href="mailto:dave@boost-consulting.com">David Abrahams</a>.</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,7 @@
-- Downloading https://github.com/boostorg/concept_check/archive/boost-1.79.0.tar.gz -> boostorg-concept_check-boost-1.79.0.tar.gz...
-- Extracting source D:/a/1/s/externals/vcpkg/downloads/boostorg-concept_check-boost-1.79.0.tar.gz
-- Using source at D:/a/1/s/externals/vcpkg/buildtrees/boost-concept-check/src/ost-1.79.0-c4bb71ebed.clean
-- Copying headers
-- Copying headers done
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-concept-check_x64-windows/share/boost-concept-check/usage
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-concept-check_x64-windows/share/boost-concept-check/copyright

View File

@@ -0,0 +1,16 @@
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-preprocessor bf16615c7acc80769793c4f62c492a31cf3d22cd0d8393ccfd77d192da7c41b2
boost-static-assert 795e87a155fce50821163bc84e802f28dce54e4af6a3a86045f9ecec76ad4c95
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
cmake 3.23.2
features core
portfile.cmake 65586b76abb4b5ddd74697b21f58b5dad90ac629d8591c8a57bd2e442b8235b4
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 1be69ed51fefbaa6cb4c128581f0dc7532501b819662884dae91949df3992f7e
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f