├── .appveyor.yml ├── .codecov.yml ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.jam ├── doc └── readme ├── dynamic_bitset.html ├── example ├── Jamfile ├── example1.cpp ├── example2.cpp ├── example3.cpp └── timing_tests.cpp ├── include └── boost │ ├── dynamic_bitset.hpp │ ├── dynamic_bitset │ ├── config.hpp │ ├── detail │ │ ├── dynamic_bitset.hpp │ │ └── lowest_bit.hpp │ ├── dynamic_bitset.hpp │ └── serialization.hpp │ └── dynamic_bitset_fwd.hpp ├── index.html ├── meta └── libraries.json └── test ├── Jamfile.v2 ├── bitset_test.hpp ├── cmake_test ├── CMakeLists.txt └── main.cpp ├── dyn_bitset_unit_tests1.cpp ├── dyn_bitset_unit_tests2.cpp ├── dyn_bitset_unit_tests3.cpp ├── dyn_bitset_unit_tests4.cpp ├── dyn_bitset_unit_tests5.cpp ├── test_ambiguous_set.cpp ├── test_boost_hash.cpp ├── test_lowest_bit.cpp └── test_std_hash.cpp /.appveyor.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2016, 2017 Peter Dimov 2 | # Copyright 2017 - 2019 James E. King III 3 | # Copyright 2019 - 2021 Alexander Grund 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 6 | 7 | # 8 | # Generic Appveyor build script for boostorg repositories 9 | # See: https://github.com/boostorg/boost-ci/ 10 | # 11 | # Instructions for customizing this script for your library: 12 | # 13 | # 1. Customize the compilers and language levels you want. 14 | # 2. If you have more than include/, src/, test/, example/, examples/, 15 | # benchmark/ or tools/ directories, set the environment variable DEPINST. 16 | # For example if your build uses code in "bench/" and "fog/" directories: 17 | # - DEPINST: --include bench --include fog 18 | # 3. Enable pull request builds in your boostorg/ account. 19 | # 20 | # That's it - the script will do everything else for you. 21 | # 22 | 23 | version: 1.0.{build}-{branch} 24 | 25 | shallow_clone: true 26 | 27 | branches: 28 | only: 29 | - master 30 | - develop 31 | - /bugfix\/.*/ 32 | - /feature\/.*/ 33 | - /fix\/.*/ 34 | - /pr\/.*/ 35 | 36 | skip_commits: 37 | files: 38 | - LICENSE 39 | - meta/* 40 | - README.md 41 | 42 | matrix: 43 | fast_finish: false 44 | # Adding MAYFAIL to any matrix job allows it to fail but the build stays green: 45 | allow_failures: 46 | - MAYFAIL: true 47 | 48 | environment: 49 | global: 50 | B2_CI_VERSION: 1 51 | GIT_FETCH_JOBS: 4 52 | # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties 53 | # to use the default for a given environment, comment it out; recommend you build debug and release however: 54 | # on Windows it is important to exercise all the possibilities, especially shared vs static, however most 55 | # libraries that care about this exercise it in their Jamfiles... 56 | B2_ADDRESS_MODEL: 32,64 57 | B2_LINK: shared,static 58 | # B2_THREADING: threading=multi,single 59 | B2_VARIANT: release 60 | 61 | matrix: 62 | - FLAVOR: Visual Studio 2017 C++2a Strict 63 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 64 | B2_CXXFLAGS: -permissive- 65 | B2_CXXSTD: 2a 66 | B2_TOOLSET: msvc-14.1 67 | 68 | - FLAVOR: Visual Studio 2017 C++14/17 69 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 70 | B2_CXXSTD: 14,17 71 | B2_TOOLSET: msvc-14.1 72 | 73 | - FLAVOR: cygwin (32-bit) 74 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 75 | ADDPATH: C:\cygwin\bin; 76 | B2_ADDRESS_MODEL: 32 77 | B2_CXXSTD: 11,14,1z 78 | B2_TOOLSET: gcc 79 | 80 | - FLAVOR: cygwin (64-bit) 81 | APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 82 | ADDPATH: C:\cygwin64\bin; 83 | B2_ADDRESS_MODEL: 64 84 | B2_CXXSTD: 11,14,1z 85 | B2_TOOLSET: gcc 86 | 87 | install: 88 | - git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned 89 | # Copy ci folder if not testing Boost.CI 90 | - if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci 91 | - rmdir /s /q C:\boost-ci-cloned 92 | - ci\appveyor\install.bat 93 | 94 | build: off 95 | 96 | test_script: ci\build.bat 97 | 98 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 - 2021 Alexander Grund 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 4 | # 5 | # Sample codecov configuration file. Edit as required 6 | 7 | codecov: 8 | max_report_age: off 9 | require_ci_to_pass: yes 10 | notify: 11 | # Increase this if you have multiple coverage collection jobs 12 | after_n_builds: 2 13 | wait_for_ci: yes 14 | 15 | parsers: 16 | gcov: 17 | branch_detection: 18 | conditional: yes 19 | loop: yes 20 | method: no 21 | macro: no 22 | 23 | # Change how pull request comments look 24 | comment: 25 | layout: "reach,diff,flags,files,footer" 26 | 27 | # Ignore specific files or folders. Glob patterns are supported. 28 | # See https://docs.codecov.com/docs/ignoring-paths 29 | ignore: 30 | - libs/dynamic_bitset/test/ 31 | - test/ 32 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto !eol svneol=native#text/plain 2 | *.gitattributes text svneol=native#text/plain 3 | 4 | # Scriptish formats 5 | *.bat text svneol=native#text/plain 6 | *.bsh text svneol=native#text/x-beanshell 7 | *.cgi text svneol=native#text/plain 8 | *.cmd text svneol=native#text/plain 9 | *.js text svneol=native#text/javascript 10 | *.php text svneol=native#text/x-php 11 | *.pl text svneol=native#text/x-perl 12 | *.pm text svneol=native#text/x-perl 13 | *.py text svneol=native#text/x-python 14 | *.sh eol=lf svneol=LF#text/x-sh 15 | configure eol=lf svneol=LF#text/x-sh 16 | 17 | # Image formats 18 | *.bmp binary svneol=unset#image/bmp 19 | *.gif binary svneol=unset#image/gif 20 | *.ico binary svneol=unset#image/ico 21 | *.jpeg binary svneol=unset#image/jpeg 22 | *.jpg binary svneol=unset#image/jpeg 23 | *.png binary svneol=unset#image/png 24 | *.tif binary svneol=unset#image/tiff 25 | *.tiff binary svneol=unset#image/tiff 26 | *.svg text svneol=native#image/svg%2Bxml 27 | 28 | # Data formats 29 | *.pdf binary svneol=unset#application/pdf 30 | *.avi binary svneol=unset#video/avi 31 | *.doc binary svneol=unset#application/msword 32 | *.dsp text svneol=crlf#text/plain 33 | *.dsw text svneol=crlf#text/plain 34 | *.eps binary svneol=unset#application/postscript 35 | *.gz binary svneol=unset#application/gzip 36 | *.mov binary svneol=unset#video/quicktime 37 | *.mp3 binary svneol=unset#audio/mpeg 38 | *.ppt binary svneol=unset#application/vnd.ms-powerpoint 39 | *.ps binary svneol=unset#application/postscript 40 | *.psd binary svneol=unset#application/photoshop 41 | *.rdf binary svneol=unset#text/rdf 42 | *.rss text svneol=unset#text/xml 43 | *.rtf binary svneol=unset#text/rtf 44 | *.sln text svneol=native#text/plain 45 | *.swf binary svneol=unset#application/x-shockwave-flash 46 | *.tgz binary svneol=unset#application/gzip 47 | *.vcproj text svneol=native#text/xml 48 | *.vcxproj text svneol=native#text/xml 49 | *.vsprops text svneol=native#text/xml 50 | *.wav binary svneol=unset#audio/wav 51 | *.xls binary svneol=unset#application/vnd.ms-excel 52 | *.zip binary svneol=unset#application/zip 53 | 54 | # Text formats 55 | .htaccess text svneol=native#text/plain 56 | *.bbk text svneol=native#text/xml 57 | *.cmake text svneol=native#text/plain 58 | *.css text svneol=native#text/css 59 | *.dtd text svneol=native#text/xml 60 | *.htm text svneol=native#text/html 61 | *.html text svneol=native#text/html 62 | *.ini text svneol=native#text/plain 63 | *.log text svneol=native#text/plain 64 | *.mak text svneol=native#text/plain 65 | *.qbk text svneol=native#text/plain 66 | *.rst text svneol=native#text/plain 67 | *.sql text svneol=native#text/x-sql 68 | *.txt text svneol=native#text/plain 69 | *.xhtml text svneol=native#text/xhtml%2Bxml 70 | *.xml text svneol=native#text/xml 71 | *.xsd text svneol=native#text/xml 72 | *.xsl text svneol=native#text/xml 73 | *.xslt text svneol=native#text/xml 74 | *.xul text svneol=native#text/xul 75 | *.yml text svneol=native#text/plain 76 | boost-no-inspect text svneol=native#text/plain 77 | CHANGES text svneol=native#text/plain 78 | COPYING text svneol=native#text/plain 79 | INSTALL text svneol=native#text/plain 80 | Jamfile text svneol=native#text/plain 81 | Jamroot text svneol=native#text/plain 82 | Jamfile.v2 text svneol=native#text/plain 83 | Jamrules text svneol=native#text/plain 84 | Makefile* text svneol=native#text/plain 85 | README text svneol=native#text/plain 86 | TODO text svneol=native#text/plain 87 | 88 | # Code formats 89 | *.c text svneol=native#text/plain 90 | *.cpp text svneol=native#text/plain 91 | *.h text svneol=native#text/plain 92 | *.hpp text svneol=native#text/plain 93 | *.ipp text svneol=native#text/plain 94 | *.tpp text svneol=native#text/plain 95 | *.jam text svneol=native#text/plain 96 | *.java text svneol=native#text/plain 97 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020-2021 Peter Dimov 2 | # Copyright 2021 Andrey Semashev 3 | # Copyright 2021 Alexander Grund 4 | # Copyright 2022-2024 James E. King III 5 | # 6 | # Distributed under the Boost Software License, Version 1.0. 7 | # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 8 | --- 9 | name: CI 10 | 11 | on: 12 | pull_request: 13 | push: 14 | branches: 15 | - master 16 | - develop 17 | - bugfix/** 18 | - feature/** 19 | - fix/** 20 | - pr/** 21 | paths-ignore: 22 | - LICENSE 23 | - meta/** 24 | - README.md 25 | 26 | concurrency: 27 | group: ${{format('{0}:{1}', github.repository, github.ref)}} 28 | cancel-in-progress: true 29 | 30 | env: 31 | GIT_FETCH_JOBS: 8 32 | NET_RETRY_COUNT: 5 33 | B2_CI_VERSION: 1 34 | B2_VARIANT: debug,release 35 | B2_LINK: shared,static 36 | LCOV_BRANCH_COVERAGE: 0 37 | 38 | jobs: 39 | posix: 40 | defaults: 41 | run: 42 | shell: bash 43 | 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | include: 48 | # linux, gcc 49 | - { compiler: gcc-7, cxxstd: '11,14,17', os: ubuntu-20.04 } 50 | - { compiler: gcc-8, cxxstd: '11,14,17,2a', os: ubuntu-20.04 } 51 | - { compiler: gcc-9, cxxstd: '11,14,17,2a', os: ubuntu-20.04 } 52 | - { compiler: gcc-10, cxxstd: '11,14,17,20', os: ubuntu-20.04 } 53 | - { compiler: gcc-11, cxxstd: '11,14,17,20', os: ubuntu-20.04 } 54 | - { compiler: gcc-12, cxxstd: '11,14,17,20', os: ubuntu-22.04 } 55 | - { compiler: gcc-13, cxxstd: '11,14,17,20,2b', os: ubuntu-22.04 } 56 | - { compiler: gcc-14, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04 } 57 | - { name: GCC w/ sanitizers, sanitize: yes, 58 | compiler: gcc-13, cxxstd: '11,14,17,20', os: ubuntu-22.04 } 59 | - { name: Collect coverage, coverage: yes, 60 | compiler: gcc-12, cxxstd: '11', os: ubuntu-22.04, install: 'g++-12-multilib', address-model: '32,64' } 61 | 62 | # linux, clang 63 | - { compiler: clang-9, cxxstd: '11,14,17,2a', os: ubuntu-20.04 } 64 | - { compiler: clang-10, cxxstd: '11,14,17,20', os: ubuntu-20.04 } 65 | - { compiler: clang-11, cxxstd: '11,14,17,20', os: ubuntu-20.04 } 66 | - { compiler: clang-12, cxxstd: '11,14,17,20', os: ubuntu-20.04 } 67 | # Clang isn't compatible with libstdc++-13, so use the slightly older one 68 | - { compiler: clang-13, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-13 g++-12', gcc_toolchain: 12 } 69 | - { compiler: clang-14, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-14 g++-12', gcc_toolchain: 12 } 70 | - { compiler: clang-15, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-15 g++-12', gcc_toolchain: 12 } 71 | - { compiler: clang-16, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04 } 72 | # https://github.com/llvm/llvm-project/issues/59827: disabled 2b/23 for clang-17 with libstdc++13 in 24.04 73 | - { compiler: clang-17, cxxstd: '11,14,17,20', os: ubuntu-24.04 } 74 | - { compiler: clang-18, cxxstd: '11,17,20,23,2c', os: ubuntu-24.04 } 75 | 76 | # linux, libc++ 77 | - { name: Clang w/ sanitizers, sanitize: yes, 78 | compiler: clang-12, cxxstd: '11,14,17,20', os: ubuntu-20.04, stdlib: 'libc++', install: 'clang-12 libc++-12-dev libc++abi-12-dev' } 79 | 80 | - { name: MacOS w/ clang and sanitizers, 81 | compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-13, sanitize: yes } 82 | - { compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-14 } 83 | - { compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-15 } 84 | 85 | # Coverity Scan 86 | # requires two github secrets in repo to activate; see ci/github/coverity.sh 87 | # does not run on pull requests, only on pushes into develop and master 88 | - { name: Coverity, coverity: yes, 89 | compiler: clang-12, cxxstd: '17', os: ubuntu-20.04, ccache: no } 90 | 91 | # multiarch (bigendian testing) - does not support coverage yet 92 | - { name: Big-endian, multiarch: yes, 93 | compiler: clang, cxxstd: '17', os: ubuntu-22.04, ccache: no, distro: fedora, edition: 34, arch: s390x } 94 | 95 | timeout-minutes: 120 96 | runs-on: ${{matrix.os}} 97 | env: {B2_USE_CCACHE: 1} 98 | 99 | steps: 100 | - name: Setup environment 101 | run: | 102 | if [ -f "/etc/debian_version" ]; then 103 | echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV 104 | export DEBIAN_FRONTEND=noninteractive 105 | fi 106 | if [ -n "${{matrix.container}}" ] && [ -f "/etc/debian_version" ]; then 107 | apt-get -o Acquire::Retries=$NET_RETRY_COUNT update 108 | apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common curl 109 | # Need (newer) git, and the older Ubuntu container may require requesting the key manually using port 80 110 | curl -sSL --retry ${NET_RETRY_COUNT:-5} 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xE1DD270288B4E6030699E45FA1715D88E1DF1F24' | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/git-core_ubuntu_ppa.gpg 111 | for i in {1..${NET_RETRY_COUNT:-3}}; do sudo -E add-apt-repository -y ppa:git-core/ppa && break || sleep 10; done 112 | apt-get -o Acquire::Retries=$NET_RETRY_COUNT update 113 | osver=$(lsb_release -sr | cut -f1 -d.) 114 | pkgs="g++ git xz-utils" 115 | # Ubuntu 22+ has only Python 3 in the repos 116 | if [ -n "$osver" ] && [ "$osver" -ge "22" ]; then 117 | pkgs+=" python-is-python3 libpython3-dev" 118 | else 119 | pkgs+=" python libpython-dev" 120 | fi 121 | apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs 122 | fi 123 | # For jobs not compatible with ccache, use "ccache: no" in the matrix 124 | if [[ "${{ matrix.ccache }}" == "no" ]]; then 125 | echo "B2_USE_CCACHE=0" >> $GITHUB_ENV 126 | fi 127 | git config --global pack.threads 0 128 | if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then 129 | # Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590 130 | curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217 131 | fi 132 | 133 | - uses: actions/checkout@v4 134 | with: 135 | # For coverage builds fetch the whole history, else only 1 commit using a 'fake ternary' 136 | fetch-depth: ${{ matrix.coverage && '0' || '1' }} 137 | 138 | - name: Cache ccache 139 | uses: actions/cache@v4 140 | if: env.B2_USE_CCACHE 141 | with: 142 | path: ~/.ccache 143 | key: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-${{github.sha}} 144 | restore-keys: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}- 145 | 146 | - name: Fetch Boost.CI 147 | uses: actions/checkout@v4 148 | with: 149 | repository: boostorg/boost-ci 150 | ref: master 151 | path: boost-ci-cloned 152 | 153 | - name: Get CI scripts folder 154 | run: | 155 | # Copy ci folder if not testing Boost.CI 156 | [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . 157 | rm -rf boost-ci-cloned 158 | 159 | - name: Install packages 160 | if: startsWith(matrix.os, 'ubuntu') 161 | run: | 162 | SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}") 163 | SOURCES=("${{join(matrix.sources, '" "')}}") 164 | # Add this by default 165 | SOURCE_KEYS+=('http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1E9377A2BA9EF27F') 166 | SOURCES+=(ppa:ubuntu-toolchain-r/test) 167 | 168 | ci/add-apt-keys.sh "${SOURCE_KEYS[@]}" 169 | # Initial update before adding sources required to get e.g. keys 170 | sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update 171 | ci/add-apt-repositories.sh "${SOURCES[@]}" 172 | 173 | sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update 174 | if [[ -z "${{matrix.install}}" ]]; then 175 | pkgs="${{matrix.compiler}}" 176 | pkgs="${pkgs/gcc-/g++-}" 177 | else 178 | pkgs="${{matrix.install}}" 179 | fi 180 | sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs 181 | 182 | - name: Setup GCC Toolchain 183 | if: matrix.gcc_toolchain 184 | run: | 185 | GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" 186 | echo "GCC_TOOLCHAIN_ROOT=$GCC_TOOLCHAIN_ROOT" >> $GITHUB_ENV 187 | if ! command -v dpkg-architecture; then 188 | apt-get install -y dpkg-dev 189 | fi 190 | MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" 191 | mkdir -p "$GCC_TOOLCHAIN_ROOT" 192 | ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" 193 | ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" 194 | mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" 195 | ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" 196 | 197 | - name: Setup multiarch 198 | if: matrix.multiarch 199 | env: 200 | BDDE_DISTRO: ${{matrix.distro}} 201 | BDDE_EDITION: ${{matrix.edition}} 202 | BDDE_ARCH: ${{matrix.arch}} 203 | run: ci/github/setup_bdde.sh 204 | 205 | - name: Setup Boost 206 | env: 207 | B2_ADDRESS_MODEL: ${{matrix.address-model}} 208 | B2_COMPILER: ${{matrix.compiler}} 209 | B2_CXXSTD: ${{matrix.cxxstd}} 210 | B2_SANITIZE: ${{matrix.sanitize}} 211 | B2_STDLIB: ${{matrix.stdlib}} 212 | # More entries can be added in the same way, see the B2_ARGS assignment in ci/enforce.sh for the possible keys. 213 | # B2_DEFINES: ${{matrix.defines}} 214 | # Variables set here (to non-empty) will override the top-level environment variables, e.g. 215 | # B2_VARIANT: ${{matrix.variant}} 216 | # Set the (B2) target(s) to build, defaults to the test folder of the current library 217 | # Can alternatively be done like this in the build step or in the build command of the build step, e.g. `run: B2_TARGETS=libs/$SELF/doc ci/build.sh` 218 | # B2_TARGETS: libs/foo/test//bar 219 | run: source ci/github/install.sh 220 | 221 | - name: Setup coverage collection 222 | if: matrix.coverage 223 | run: ci/github/codecov.sh "setup" 224 | 225 | - name: Run tests 226 | if: '!matrix.coverity' 227 | run: ci/build.sh 228 | 229 | - name: Upload coverage 230 | if: matrix.coverage 231 | run: ci/codecov.sh "upload" 232 | env: 233 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 234 | 235 | - name: Run coverity 236 | if: matrix.coverity && github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'master') 237 | run: ci/github/coverity.sh 238 | env: 239 | COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }} 240 | COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }} 241 | 242 | windows: 243 | defaults: 244 | run: 245 | shell: cmd 246 | strategy: 247 | fail-fast: false 248 | matrix: 249 | include: 250 | - { toolset: msvc-14.0, cxxstd: '14,latest', addrmd: '32,64', os: windows-2019 } 251 | - { toolset: msvc-14.2, cxxstd: '14,17,20', addrmd: '32,64', os: windows-2019 } 252 | - { toolset: msvc-14.3, cxxstd: '14,17,20,latest',addrmd: '32,64', os: windows-2022 } 253 | - { name: Collect coverage, coverage: yes, 254 | toolset: msvc-14.3, cxxstd: 'latest', addrmd: '64', os: windows-2022 } 255 | - { toolset: clang-win, cxxstd: '14,17,latest', addrmd: '32,64', os: windows-2022 } 256 | - { toolset: gcc, cxxstd: '11,14,17,2a', addrmd: '64', os: windows-2019 } 257 | 258 | runs-on: ${{matrix.os}} 259 | 260 | steps: 261 | - uses: actions/checkout@v4 262 | 263 | - name: Fetch Boost.CI 264 | uses: actions/checkout@v4 265 | with: 266 | repository: boostorg/boost-ci 267 | ref: master 268 | path: boost-ci-cloned 269 | - name: Get CI scripts folder 270 | run: | 271 | REM Copy ci folder if not testing Boost.CI 272 | if "%GITHUB_REPOSITORY%" == "%GITHUB_REPOSITORY:boost-ci=%" xcopy /s /e /q /i /y boost-ci-cloned\ci .\ci 273 | rmdir /s /q boost-ci-cloned 274 | 275 | - name: Setup Boost 276 | run: ci\github\install.bat 277 | 278 | - name: Run tests 279 | if: '!matrix.coverage' 280 | run: ci\build.bat 281 | env: 282 | B2_TOOLSET: ${{matrix.toolset}} 283 | B2_CXXSTD: ${{matrix.cxxstd}} 284 | B2_ADDRESS_MODEL: ${{matrix.addrmd}} 285 | 286 | - name: Collect coverage 287 | shell: powershell 288 | if: matrix.coverage 289 | run: ci\opencppcoverage.ps1 290 | env: 291 | B2_TOOLSET: ${{matrix.toolset}} 292 | B2_CXXSTD: ${{matrix.cxxstd}} 293 | B2_ADDRESS_MODEL: ${{matrix.addrmd}} 294 | 295 | - name: Upload coverage 296 | if: matrix.coverage 297 | uses: codecov/codecov-action@v5 298 | with: 299 | disable_search: true 300 | fail_ci_if_error: true 301 | files: __out/cobertura.xml 302 | name: github-actions 303 | token: ${{secrets.CODECOV_TOKEN}} 304 | verbose: true 305 | 306 | MSYS2: 307 | defaults: 308 | run: 309 | shell: msys2 {0} 310 | strategy: 311 | fail-fast: false 312 | matrix: 313 | include: 314 | - { sys: MINGW32, compiler: gcc, cxxstd: '11,17,20' } 315 | - { sys: MINGW64, compiler: gcc, cxxstd: '11,17,20' } 316 | 317 | runs-on: windows-latest 318 | 319 | steps: 320 | - uses: actions/checkout@v4 321 | 322 | - name: Setup MSYS2 environment 323 | uses: msys2/setup-msys2@v2 324 | with: 325 | msystem: ${{matrix.sys}} 326 | update: true 327 | install: git python 328 | pacboy: gcc:p cmake:p ninja:p 329 | 330 | - name: Fetch Boost.CI 331 | uses: actions/checkout@v4 332 | with: 333 | repository: boostorg/boost-ci 334 | ref: master 335 | path: boost-ci-cloned 336 | - name: Get CI scripts folder 337 | run: | 338 | # Copy ci folder if not testing Boost.CI 339 | [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . 340 | rm -rf boost-ci-cloned 341 | 342 | - name: Setup Boost 343 | env: 344 | B2_COMPILER: ${{matrix.compiler}} 345 | B2_CXXSTD: ${{matrix.cxxstd}} 346 | B2_SANITIZE: ${{matrix.sanitize}} 347 | B2_STDLIB: ${{matrix.stdlib}} 348 | run: ci/github/install.sh 349 | 350 | - name: Run tests 351 | run: ci/build.sh 352 | 353 | # Run also the CMake tests to avoid having to setup another matrix for CMake on MSYS 354 | - name: Run CMake tests 355 | run: | 356 | cd "$BOOST_ROOT" 357 | mkdir __build_cmake_test__ && cd __build_cmake_test__ 358 | cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DBoost_VERBOSE=ON .. 359 | cmake --build . --target tests --config Debug -j$B2_JOBS 360 | ctest --output-on-failure --build-config Debug 361 | 362 | CMake: 363 | defaults: 364 | run: 365 | shell: bash 366 | 367 | strategy: 368 | fail-fast: false 369 | matrix: 370 | include: 371 | - { os: ubuntu-20.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' } 372 | - { os: ubuntu-20.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' } 373 | - { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' } 374 | - { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' } 375 | 376 | timeout-minutes: 120 377 | runs-on: ${{matrix.os}} 378 | 379 | steps: 380 | - uses: actions/checkout@v4 381 | - name: Fetch Boost.CI 382 | uses: actions/checkout@v4 383 | with: 384 | repository: boostorg/boost-ci 385 | ref: master 386 | path: boost-ci-cloned 387 | - name: Get CI scripts folder 388 | run: | 389 | # Copy ci folder if not testing Boost.CI 390 | [[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci . 391 | rm -rf boost-ci-cloned 392 | - name: Setup Boost 393 | env: {B2_DONT_BOOTSTRAP: 1} 394 | run: source ci/github/install.sh 395 | 396 | - name: Run CMake tests 397 | run: | 398 | cd "$BOOST_ROOT" 399 | mkdir __build_cmake_test__ && cd __build_cmake_test__ 400 | cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON .. 401 | cmake --build . --target tests --config ${{matrix.build_type}} -j$B2_JOBS 402 | ctest --output-on-failure --build-config ${{matrix.build_type}} 403 | 404 | - name: Run CMake subdir tests 405 | run: | 406 | cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder 407 | [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test" 408 | cd "$cmake_test_folder" 409 | mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__ 410 | cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} .. 411 | cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS 412 | ctest --output-on-failure --build-config ${{matrix.build_type}} 413 | 414 | - name: Install Library 415 | run: | 416 | cd "$BOOST_ROOT" 417 | mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ 418 | cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON .. 419 | cmake --build . --target install --config ${{matrix.build_type}} -j$B2_JOBS 420 | - name: Run CMake install tests 421 | run: | 422 | cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder 423 | [ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test" 424 | cd "$cmake_test_folder" 425 | mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__ 426 | cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local .. 427 | cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS 428 | ctest --output-on-failure --build-config ${{matrix.build_type}} 429 | 430 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Generated by `boostdep --cmake dynamic_bitset` 2 | # Copyright 2020 Peter Dimov 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # https://www.boost.org/LICENSE_1_0.txt 5 | 6 | cmake_minimum_required(VERSION 3.5...3.16) 7 | 8 | project(boost_dynamic_bitset VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) 9 | 10 | add_library(boost_dynamic_bitset INTERFACE) 11 | add_library(Boost::dynamic_bitset ALIAS boost_dynamic_bitset) 12 | 13 | target_include_directories(boost_dynamic_bitset INTERFACE include) 14 | 15 | target_link_libraries(boost_dynamic_bitset 16 | INTERFACE 17 | Boost::assert 18 | Boost::config 19 | Boost::container_hash 20 | Boost::core 21 | Boost::integer 22 | Boost::move 23 | Boost::static_assert 24 | Boost::throw_exception 25 | ) 26 | 27 | if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") 28 | 29 | add_subdirectory(test) 30 | 31 | endif() 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DynamicBitset, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), is similar to std::bitset however the size is specified at run-time instead of at compile-time. 2 | 3 | ### License 4 | 5 | Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). 6 | 7 | ### Properties 8 | 9 | * C++11 10 | * Header-only 11 | 12 | ### Build Status 13 | 14 | 15 | | Branch | GHA CI | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | 16 | | :-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | 17 | | [`master`](https://github.com/boostorg/dynamic_bitset/tree/master) | [![Build Status](https://github.com/boostorg/dynamic_bitset/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/dynamic_bitset/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/n7bki5ka3v918r5r/branch/master?svg=true)](https://ci.appveyor.com/project/cppalliance/dynamic-bitset/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16167/badge.svg)](https://scan.coverity.com/projects/boostorg-dynamic_bitset) | [![codecov](https://codecov.io/gh/boostorg/dynamic_bitset/branch/master/graph/badge.svg?token=PVG5jth1ez)](https://codecov.io/gh/boostorg/dynamic_bitset/tree/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/dynamic_bitset.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/dynamic_bitset) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://www.boost.org/development/tests/master/developer/dynamic_bitset.html) 18 | | [`develop`](https://github.com/boostorg/dynamic_bitset/tree/develop) | [![Build Status](https://github.com/boostorg/dynamic_bitset/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/dynamic_bitset/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/n7bki5ka3v918r5r/branch/develop?svg=true)](https://ci.appveyor.com/project/cppalliance/dynamic-bitset/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16167/badge.svg)](https://scan.coverity.com/projects/boostorg-dynamic_bitset) | [![codecov](https://codecov.io/gh/boostorg/dynamic_bitset/branch/develop/graph/badge.svg?token=PVG5jth1ez)](https://codecov.io/gh/boostorg/dynamic_bitset/tree/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/dynamic_bitset.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/dynamic_bitset) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://www.boost.org/development/tests/develop/developer/dynamic_bitset.html) 19 | 20 | ### Directories 21 | 22 | | Name | Purpose | 23 | | ----------- | ------------------------------ | 24 | | `example` | examples | 25 | | `doc` | documentation | 26 | | `include` | headers | 27 | | `test` | unit tests | 28 | 29 | ### More information 30 | 31 | * [Ask questions](https://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-dynamic_bitset) 32 | * [Report bugs](https://github.com/boostorg/dynamic_bitset/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. 33 | * Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). 34 | * Discussions about the library are held on the [Boost developers mailing list](https://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](https://www.boost.org/community/policy.html) before posting and add the `[dynamic_bitset]` tag at the beginning of the subject line. 35 | -------------------------------------------------------------------------------- /build.jam: -------------------------------------------------------------------------------- 1 | # Copyright René Ferdinand Rivera Morell 2023-2024 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # (See accompanying file LICENSE_1_0.txt or copy at 4 | # http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | require-b2 5.2 ; 7 | 8 | constant boost_dependencies : 9 | /boost/assert//boost_assert 10 | /boost/config//boost_config 11 | /boost/container_hash//boost_container_hash 12 | /boost/core//boost_core 13 | /boost/integer//boost_integer 14 | /boost/move//boost_move 15 | /boost/static_assert//boost_static_assert 16 | /boost/throw_exception//boost_throw_exception ; 17 | 18 | project /boost/dynamic_bitset 19 | : common-requirements 20 | include 21 | ; 22 | 23 | explicit 24 | [ alias boost_dynamic_bitset : : : : $(boost_dependencies) ] 25 | [ alias all : boost_dynamic_bitset example test ] 26 | ; 27 | 28 | call-if : boost-library dynamic_bitset 29 | ; 30 | 31 | -------------------------------------------------------------------------------- /doc/readme: -------------------------------------------------------------------------------- 1 | The documentation for the dynamic_bitset library is the top-level index.html file. -------------------------------------------------------------------------------- /example/Jamfile: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------- 2 | # Copyright (c) 2002 Gennaro Prota 3 | # 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE_1_0.txt or copy at 6 | # http://www.boost.org/LICENSE_1_0.txt) 7 | # 8 | # ----------------------------------------------------------- 9 | 10 | project : requirements /boost/dynamic_bitset//boost_dynamic_bitset ; 11 | 12 | exe timing_tests 13 | : timing_tests.cpp 14 | /boost/timer//boost_timer 15 | /boost/detail//boost_detail 16 | ; 17 | 18 | exe example1 19 | : example1.cpp 20 | ; 21 | 22 | exe example2 23 | : example2.cpp 24 | ; 25 | 26 | exe example3 27 | : example3.cpp 28 | ; 29 | 30 | -------------------------------------------------------------------------------- /example/example1.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2001. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | 6 | 7 | 8 | // An example of setting and reading some bits. Note that operator[] 9 | // goes from the least-significant bit at 0 to the most significant 10 | // bit at size()-1. The operator<< for dynamic_bitset prints the 11 | // bitset from most-significant to least-significant, since that is 12 | // the format most people are used to reading. 13 | // 14 | // The output is: 15 | // 16 | // 11001 17 | // 10011 18 | // --------------------------------------------------------------------- 19 | 20 | #include 21 | #include 22 | 23 | int main() 24 | { 25 | boost::dynamic_bitset<> x(5); // all 0's by default 26 | x[0] = 1; 27 | x[1] = 1; 28 | x[4] = 1; 29 | for (boost::dynamic_bitset<>::size_type i = 0; i < x.size(); ++i) 30 | std::cout << x[i]; 31 | std::cout << "\n"; 32 | std::cout << x << "\n"; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /example/example2.cpp: -------------------------------------------------------------------------------- 1 | // (C) Copyright Jeremy Siek 2001. 2 | // Distributed under the Boost Software License, Version 1.0. (See 3 | // accompanying file LICENSE_1_0.txt or copy at 4 | // http://www.boost.org/LICENSE_1_0.txt) 5 | // 6 | // Sample output: 7 | // 8 | // bits(0) = 00 9 | // bits(1) = 01 10 | // bits(2) = 10 11 | // bits(3) = 11 12 | 13 | 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | const boost::dynamic_bitset<> b0(2, 0ul); 20 | std::cout << "bits(0) = " << b0 << std::endl; 21 | 22 | const boost::dynamic_bitset<> b1(2, 1ul); 23 | std::cout << "bits(1) = " << b1 << std::endl; 24 | 25 | const boost::dynamic_bitset<> b2(2, 2ul); 26 | std::cout << "bits(2) = " << b2 << std::endl; 27 | 28 | const boost::dynamic_bitset<> b3(2, 3ul); 29 | std::cout << "bits(3) = " << b3 << std::endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /example/example3.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2001 Jeremy Siek 2 | // Copyright (c) 2008 Gennaro Prota 3 | // Distributed under the Boost Software License, Version 1.0. (See 4 | // accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | // Sample run: 8 | // 9 | // mask = 101010101010 10 | // x.size() = 0 11 | // Enter a bitset in binary: x = 100100010 12 | // 13 | // Input number: 100100010 14 | // x.size() is now: 9 15 | // As unsigned long: 290 16 | // Mask (possibly resized): 010101010 17 | // And with mask: 000100010 18 | // Or with mask: 110101010 19 | // Shifted left by 1: 001000100 20 | // Shifted right by 1: 010010001 21 | 22 | 23 | 24 | #include "boost/dynamic_bitset.hpp" 25 | 26 | #include 27 | #include 28 | 29 | int main() 30 | { 31 | boost::dynamic_bitset<> mask(12, 2730ul); 32 | std::cout << "mask = " << mask << std::endl; 33 | 34 | boost::dynamic_bitset<> x; 35 | std::cout << "x.size() = " << x.size() << std::endl; 36 | 37 | std::cout << "Enter a bitset in binary: x = " << std::flush; 38 | if (std::cin >> x) { 39 | const std::size_t sz = x.size(); 40 | std::cout << std::endl; 41 | std::cout << "Input number: " << x << std::endl; 42 | std::cout << "x.size() is now: " << sz << std::endl; 43 | 44 | bool fits_in_ulong = true; 45 | unsigned long ul = 0; 46 | try { 47 | ul = x.to_ulong(); 48 | } catch(std::overflow_error &) { 49 | fits_in_ulong = false; 50 | } 51 | 52 | std::cout << "As unsigned long: "; 53 | if(fits_in_ulong) { 54 | std::cout << ul; 55 | } else { 56 | std::cout << "(overflow exception)"; 57 | } 58 | 59 | std::cout << std::endl; 60 | 61 | mask.resize(sz); 62 | 63 | std::cout << "Mask (possibly resized): " << mask << std::endl; 64 | 65 | std::cout << "And with mask: " << (x & mask) << std::endl; 66 | std::cout << "Or with mask: " << (x | mask) << std::endl; 67 | std::cout << "Shifted left by 1: " << (x << 1) << std::endl; 68 | std::cout << "Shifted right by 1: " << (x >> 1) << std::endl; 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /example/timing_tests.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2003-2004 Gennaro Prota 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // ----------------------------------------------------------- 10 | 11 | // boost::dynamic_bitset timing tests 12 | // 13 | // NOTE: 14 | // ~~~~~ 15 | // This is a preliminary, incomplete version. 16 | // 17 | // If you are interested in having more benchmarks please make a 18 | // request on the boost list, which could encourage me to continue 19 | // this work. 20 | 21 | // Also, if you use boost::dynamic_bitset on a platform where 22 | // CHAR_BIT >= 9 I suggest experimenting with the size of the count 23 | // table in detail/dynamic_bitset.hpp and report any interesting 24 | // discovery on the list as well. 25 | 26 | // You might also want to try both counting methods (by_bytes vs. 27 | // by_blocks) to see if the one that is selected automatically is 28 | // actually the fastest on your system. 29 | 30 | // 31 | // 32 | // -----------------------------------------------------------------------// 33 | 34 | 35 | #include "boost/config.hpp" 36 | 37 | #if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS) 38 | // for pre 3.0 versions of libstdc++ 39 | # define BOOST_OLD_IOSTREAMS 40 | #endif 41 | // ------------------------------------------------- // 42 | 43 | #include 44 | #include 45 | #if !defined(BOOST_OLD_IOSTREAMS) 46 | # include 47 | #endif 48 | 49 | 50 | #include "boost/cstdlib.hpp" 51 | #include "boost/version.hpp" 52 | #include "boost/timer/timer.hpp" 53 | #include "boost/dynamic_bitset.hpp" 54 | 55 | 56 | namespace { 57 | 58 | // the m_ prefixes, below, are mainly to avoid problems with g++: 59 | // see http://gcc.gnu.org/ml/gcc-bugs/1999-03n/msg00884.html 60 | // 61 | class boost_version { 62 | int m_major; 63 | int m_minor; 64 | int m_subminor; 65 | 66 | public: 67 | boost_version(unsigned long v = BOOST_VERSION): 68 | m_major(v / 100000), m_minor(v / 100 % 1000), m_subminor(v % 100) {} 69 | 70 | friend std::ostream & operator<<(std::ostream &, const boost_version &); 71 | }; 72 | 73 | 74 | // give up using basic_ostream, to avoid headaches with old libraries 75 | std::ostream& operator<<(std::ostream& os, const boost_version & v) { 76 | return os << v.m_major << '.' << v.m_minor << '.' << v.m_subminor; 77 | } 78 | 79 | } 80 | 81 | 82 | void prologue() 83 | { 84 | std::cout << '\n'; 85 | std::cout << "Compiler: " << BOOST_COMPILER << '\n'; 86 | std::cout << "Std lib : " << BOOST_STDLIB << '\n'; 87 | std::cout << "Boost v.: " << boost_version() << '\n'; 88 | 89 | std::cout << '\n'; 90 | } 91 | 92 | 93 | 94 | template 95 | void timing_test(T* = 0) // dummy parameter to workaround VC6 96 | { 97 | #ifndef BOOST_NO_STRESS_TEST 98 | const unsigned long num = 30 * 100000; 99 | #else 100 | const unsigned long num = 30 * 1000; 101 | #endif 102 | 103 | 104 | // This variable is printed at the end of the test, 105 | // to prevent the optimizer from removing the call to 106 | // count() in the loop below. 107 | typename boost::dynamic_bitset::size_type dummy = 0; 108 | 109 | std::cout << "\nTimings for dynamic_bitset<" << typeid(T).name() 110 | << "> [" << num << " iterations]\n"; 111 | std::cout << "--------------------------------------------------\n"; 112 | 113 | { 114 | boost::timer::auto_cpu_timer time; 115 | 116 | const typename boost::dynamic_bitset::size_type sz = 5000; 117 | for (unsigned long i = 0; i < num; ++i) { 118 | boost::dynamic_bitset bs(sz, i); 119 | dummy += bs.count(); 120 | } 121 | } 122 | 123 | std::cout << "(total count: " << dummy << ")\n\n"; 124 | } 125 | 126 | 127 | 128 | int main() 129 | { 130 | prologue(); 131 | 132 | timing_test(); 133 | timing_test(); 134 | timing_test(); 135 | timing_test(); 136 | # ifdef BOOST_HAS_LONG_LONG 137 | timing_test< ::boost::ulong_long_type>(); 138 | # endif 139 | 140 | return boost::exit_success; 141 | } 142 | 143 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek 4 | // Copyright (c) 2003-2004, 2008 Gennaro Prota 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // ----------------------------------------------------------- 11 | 12 | #ifndef BOOST_DYNAMIC_BITSET_HPP 13 | #define BOOST_DYNAMIC_BITSET_HPP 14 | 15 | #include "boost/dynamic_bitset/dynamic_bitset.hpp" 16 | 17 | #endif // include guard 18 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset/config.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek 4 | // Copyright (c) 2003-2006, 2008 Gennaro Prota 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // ----------------------------------------------------------- 11 | 12 | #ifndef BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424 13 | #define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424 14 | 15 | #include "boost/config.hpp" 16 | #include "boost/detail/workaround.hpp" 17 | 18 | // support for pre 3.0 libstdc++ - thanks Phil Edwards! 19 | #if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS) 20 | # define BOOST_OLD_IOSTREAMS 21 | #endif 22 | 23 | // no-op function to workaround gcc bug c++/8419 24 | // 25 | namespace boost { namespace detail { 26 | template T make_non_const(T t) { return t; } 27 | }} 28 | 29 | #if defined(__GNUC__) 30 | # define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) \ 31 | (boost::detail::make_non_const(expr)) 32 | #else 33 | # define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) (expr) 34 | #endif 35 | 36 | // 37 | #if (defined BOOST_BORLANDC && BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))) \ 38 | || (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 39 | #define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS 40 | #endif 41 | 42 | // if we can't use friends then we simply expose private members 43 | // 44 | #if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS) 45 | #define BOOST_DYNAMIC_BITSET_PRIVATE public 46 | #else 47 | #define BOOST_DYNAMIC_BITSET_PRIVATE private 48 | #endif 49 | 50 | // A couple of macros to cope with libraries without locale 51 | // support. The first macro must be used to declare a reference 52 | // to a ctype facet. The second one to widen a char by using 53 | // that ctype object. If facets and locales aren't available 54 | // the first macro is a no-op and the second one just expands 55 | // to its parameter c. 56 | // 57 | #if defined (BOOST_USE_FACET) 58 | 59 | #define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) \ 60 | const std::ctype & name = \ 61 | BOOST_USE_FACET(std::ctype, loc) /**/ 62 | 63 | #define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) \ 64 | (fac.widen(c)) 65 | #else 66 | 67 | #define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) /**/ 68 | #define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) c 69 | 70 | #endif 71 | 72 | #endif // include guard 73 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset/detail/dynamic_bitset.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek 4 | // Copyright (c) 2003-2006, 2008 Gennaro Prota 5 | // Copyright (c) 2014 Glen Joseph Fernandes 6 | // (glenjofe@gmail.com) 7 | // Copyright (c) 2018 Evgeny Shulgin 8 | // Copyright (c) 2019 Andrey Semashev 9 | // 10 | // Distributed under the Boost Software License, Version 1.0. 11 | // (See accompanying file LICENSE_1_0.txt or copy at 12 | // http://www.boost.org/LICENSE_1_0.txt) 13 | // 14 | // ----------------------------------------------------------- 15 | 16 | #ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP 17 | #define BOOST_DETAIL_DYNAMIC_BITSET_HPP 18 | 19 | #include 20 | #include 21 | #include "boost/config.hpp" 22 | #include "boost/detail/workaround.hpp" 23 | #include 24 | 25 | #if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) 26 | #include 27 | #endif 28 | 29 | namespace boost { 30 | 31 | namespace detail { 32 | namespace dynamic_bitset_impl { 33 | 34 | template 35 | struct max_limit { 36 | BOOST_STATIC_CONSTEXPR T value = static_cast(-1); 37 | }; 38 | 39 | template 40 | BOOST_CONSTEXPR_OR_CONST T max_limit::value; 41 | 42 | // Gives (read-)access to the object representation 43 | // of an object of type T (3.9p4). CANNOT be used 44 | // on a base sub-object 45 | // 46 | template 47 | inline const unsigned char * object_representation (T* p) 48 | { 49 | return static_cast(static_cast(p)); 50 | } 51 | 52 | template 53 | struct shifter 54 | { 55 | static void left_shift(T & v) { 56 | amount >= width ? (v = 0) 57 | : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount)); 58 | } 59 | }; 60 | 61 | // ------- count function implementation -------------- 62 | 63 | typedef unsigned char byte_type; 64 | 65 | // These two entities 66 | // 67 | // enum mode { access_by_bytes, access_by_blocks }; 68 | // template struct mode_to_type {}; 69 | // 70 | // were removed, since the regression logs (as of 24 Aug 2008) 71 | // showed that several compilers had troubles with recognizing 72 | // 73 | // const mode m = access_by_bytes 74 | // 75 | // as a constant expression 76 | // 77 | // * So, we'll use bool, instead of enum *. 78 | // 79 | template 80 | struct value_to_type 81 | { 82 | value_to_type() {} 83 | }; 84 | const bool access_by_bytes = true; 85 | const bool access_by_blocks = false; 86 | 87 | 88 | // the table: wrapped in a class template, so 89 | // that it is only instantiated if/when needed 90 | // 91 | template 92 | struct count_table { static const byte_type table[]; }; 93 | 94 | template <> 95 | struct count_table { /* no table */ }; 96 | 97 | 98 | const unsigned int table_width = 8; 99 | template 100 | const byte_type count_table::table[] = 101 | { 102 | // Automatically generated by GPTableGen.exe v.1.0 103 | // 104 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 105 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 106 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 107 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 108 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 109 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 110 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 111 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 112 | }; 113 | 114 | 115 | // Some platforms have fast popcount operation, that allow us to implement 116 | // counting bits much more efficiently 117 | // 118 | template 119 | BOOST_FORCEINLINE std::size_t popcount(ValueType value) BOOST_NOEXCEPT 120 | { 121 | std::size_t num = 0u; 122 | while (value) { 123 | num += count_table<>::table[value & ((1u<>= table_width; 125 | } 126 | return num; 127 | } 128 | 129 | #if (((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))) \ 130 | && (defined(__POPCNT__) || defined(__AVX__)) 131 | 132 | template <> 133 | BOOST_FORCEINLINE std::size_t popcount(unsigned short value) BOOST_NOEXCEPT 134 | { 135 | return static_cast(__popcnt16(value)); 136 | } 137 | 138 | template <> 139 | BOOST_FORCEINLINE std::size_t popcount(unsigned int value) BOOST_NOEXCEPT 140 | { 141 | return static_cast(__popcnt(value)); 142 | } 143 | 144 | template <> 145 | BOOST_FORCEINLINE std::size_t popcount(unsigned __int64 value) BOOST_NOEXCEPT 146 | { 147 | #if defined(_M_X64) 148 | return static_cast(__popcnt64(value)); 149 | #else 150 | return static_cast(__popcnt(static_cast< unsigned int >(value))) + static_cast(__popcnt(static_cast< unsigned int >(value >> 32))); 151 | #endif 152 | } 153 | 154 | #elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__)) 155 | 156 | // Note: gcc builtins are implemented by compiler runtime when the target CPU may not support the necessary instructions 157 | template <> 158 | BOOST_FORCEINLINE std::size_t popcount(unsigned short value) BOOST_NOEXCEPT 159 | { 160 | return static_cast(__builtin_popcount(static_cast(value))); 161 | } 162 | 163 | template <> 164 | BOOST_FORCEINLINE std::size_t popcount(unsigned int value) BOOST_NOEXCEPT 165 | { 166 | return static_cast(__builtin_popcount(value)); 167 | } 168 | 169 | template <> 170 | BOOST_FORCEINLINE std::size_t popcount(unsigned long value) BOOST_NOEXCEPT 171 | { 172 | return static_cast(__builtin_popcountl(value)); 173 | } 174 | 175 | template <> 176 | BOOST_FORCEINLINE std::size_t popcount(boost::ulong_long_type value) BOOST_NOEXCEPT 177 | { 178 | return static_cast(__builtin_popcountll(value)); 179 | } 180 | 181 | #endif 182 | 183 | // overload for access by blocks 184 | // 185 | template 186 | inline std::size_t do_count(Iterator first, std::size_t length, ValueType, 187 | value_to_type*) 188 | { 189 | std::size_t num1 = 0u, num2 = 0u; 190 | while (length >= 2u) { 191 | num1 += popcount(*first); 192 | ++first; 193 | num2 += popcount(*first); 194 | ++first; 195 | length -= 2u; 196 | } 197 | 198 | if (length > 0u) 199 | num1 += popcount(*first); 200 | 201 | return num1 + num2; 202 | } 203 | 204 | // overload for access by bytes 205 | // 206 | template 207 | inline std::size_t do_count(Iterator first, std::size_t length, 208 | int /*dummy param*/, 209 | value_to_type*) 210 | { 211 | if (length > 0u) { 212 | const byte_type* p = object_representation(&*first); 213 | length *= sizeof(*first); 214 | 215 | return do_count(p, length, static_cast(0u), 216 | static_cast< value_to_type* >(0)); 217 | } 218 | 219 | return 0u; 220 | } 221 | 222 | // ------------------------------------------------------- 223 | 224 | 225 | // Some library implementations simply return a dummy 226 | // value such as 227 | // 228 | // size_type(-1) / sizeof(T) 229 | // 230 | // from vector<>::max_size. This tries to get more 231 | // meaningful info. 232 | // 233 | template 234 | inline typename T::size_type vector_max_size_workaround(const T & v) 235 | BOOST_NOEXCEPT 236 | { 237 | typedef typename T::allocator_type allocator_type; 238 | 239 | const allocator_type& alloc = v.get_allocator(); 240 | 241 | typename boost::allocator_size_type::type alloc_max = 242 | boost::allocator_max_size(alloc); 243 | 244 | const typename T::size_type container_max = v.max_size(); 245 | 246 | return alloc_max < container_max ? alloc_max : container_max; 247 | } 248 | 249 | // for static_asserts 250 | template 251 | struct allowed_block_type { 252 | enum { value = T(-1) > 0 }; // ensure T has no sign 253 | }; 254 | 255 | template <> 256 | struct allowed_block_type { 257 | enum { value = false }; 258 | }; 259 | 260 | 261 | template 262 | struct is_numeric { 263 | enum { value = false }; 264 | }; 265 | 266 | # define BOOST_dynamic_bitset_is_numeric(x) \ 267 | template<> \ 268 | struct is_numeric< x > { \ 269 | enum { value = true }; \ 270 | } /**/ 271 | 272 | BOOST_dynamic_bitset_is_numeric(bool); 273 | BOOST_dynamic_bitset_is_numeric(char); 274 | 275 | #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) 276 | BOOST_dynamic_bitset_is_numeric(wchar_t); 277 | #endif 278 | 279 | BOOST_dynamic_bitset_is_numeric(signed char); 280 | BOOST_dynamic_bitset_is_numeric(short int); 281 | BOOST_dynamic_bitset_is_numeric(int); 282 | BOOST_dynamic_bitset_is_numeric(long int); 283 | 284 | BOOST_dynamic_bitset_is_numeric(unsigned char); 285 | BOOST_dynamic_bitset_is_numeric(unsigned short); 286 | BOOST_dynamic_bitset_is_numeric(unsigned int); 287 | BOOST_dynamic_bitset_is_numeric(unsigned long); 288 | 289 | #if defined(BOOST_HAS_LONG_LONG) 290 | BOOST_dynamic_bitset_is_numeric(::boost::long_long_type); 291 | BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type); 292 | #endif 293 | 294 | // intentionally omitted 295 | //BOOST_dynamic_bitset_is_numeric(float); 296 | //BOOST_dynamic_bitset_is_numeric(double); 297 | //BOOST_dynamic_bitset_is_numeric(long double); 298 | 299 | #undef BOOST_dynamic_bitset_is_numeric 300 | 301 | } // dynamic_bitset_impl 302 | } // namespace detail 303 | 304 | } // namespace boost 305 | 306 | #endif // include guard 307 | 308 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset/detail/lowest_bit.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // lowest_bit.hpp 3 | // 4 | // Position of the lowest bit 'on' 5 | // 6 | // Copyright (c) 2003-2004, 2008 Gennaro Prota 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. 9 | // (See accompanying file LICENSE_1_0.txt or copy at 10 | // http://www.boost.org/LICENSE_1_0.txt) 11 | // 12 | // ----------------------------------------------------------- 13 | 14 | #ifndef BOOST_LOWEST_BIT_HPP_GP_20030301 15 | #define BOOST_LOWEST_BIT_HPP_GP_20030301 16 | 17 | #include "boost/integer/integer_log2.hpp" 18 | #include "boost/assert.hpp" 19 | 20 | namespace boost { 21 | namespace detail { 22 | 23 | template 24 | int lowest_bit(T x) { 25 | 26 | BOOST_ASSERT(x >= 1); // PRE 27 | 28 | // clear all bits on except the rightmost one, 29 | // then calculate the logarithm base 2 30 | // 31 | return boost::integer_log2( x - ( x & (x-1) ) ); 32 | 33 | } 34 | 35 | } 36 | } 37 | 38 | 39 | #endif // include guard 40 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset/serialization.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2015 Seth Heeren 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // ----------------------------------------------------------- 10 | 11 | #ifndef BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP 12 | #define BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP 13 | 14 | #include "boost/dynamic_bitset/dynamic_bitset.hpp" 15 | #include 16 | 17 | namespace boost { 18 | 19 | // implementation for optional zero-copy serialization support 20 | template 21 | class dynamic_bitset::serialize_impl 22 | { 23 | public: 24 | template 25 | static void serialize(Ar& ar, dynamic_bitset& bs, unsigned) { 26 | ar & boost::make_nvp("m_num_bits", bs.m_num_bits) 27 | & boost::make_nvp("m_bits", bs.m_bits); 28 | } 29 | }; 30 | 31 | } 32 | 33 | // ADL hook to Boost Serialization library 34 | namespace boost { 35 | namespace serialization { 36 | 37 | template 38 | void serialize(Ar& ar, dynamic_bitset& bs, unsigned version) { 39 | dynamic_bitset::serialize_impl::serialize(ar, bs, version); 40 | } 41 | 42 | } // namespace serialization 43 | } // namespace boost 44 | 45 | #endif // include guard 46 | 47 | -------------------------------------------------------------------------------- /include/boost/dynamic_bitset_fwd.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // 3 | // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek 4 | // Copyright (c) 2003-2004 Gennaro Prota 5 | // 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See accompanying file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // ----------------------------------------------------------- 11 | 12 | #ifndef BOOST_DYNAMIC_BITSET_FWD_HPP 13 | #define BOOST_DYNAMIC_BITSET_FWD_HPP 14 | 15 | #include 16 | 17 | namespace boost { 18 | 19 | template > 21 | class dynamic_bitset; 22 | 23 | } 24 | 25 | #endif // include guard 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boostorg/dynamic_bitset/688a99f54a3854f9abc26cde6afed3135132ac02/index.html -------------------------------------------------------------------------------- /meta/libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": "dynamic_bitset", 3 | "name": "Dynamic Bitset", 4 | "authors": [ 5 | "Jeremy Siek", 6 | "Chuck Allison" 7 | ], 8 | "description": "The dynamic_bitset class represents a set of bits. It provides accesses to the value of individual bits via an operator[] and provides all of the bitwise operators that one can apply to builtin integers, such as operator& and operator<<. The number of bits in the set is specified at runtime via a parameter to the constructor of the dynamic_bitset.", 9 | "documentation": "dynamic_bitset.html", 10 | "category": [ 11 | "Containers" 12 | ], 13 | "maintainers": [ 14 | "Jeremy Siek " 15 | ], 16 | "cxxstd": "11" 17 | } 18 | -------------------------------------------------------------------------------- /test/Jamfile.v2: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright Vladimir Prus 2004 3 | # 4 | # Distributed under the Boost Software License, Version 1.0. 5 | # (See accompanying file LICENSE_1_0.txt or copy at 6 | # http://www.boost.org/LICENSE_1_0.txt) 7 | # 8 | 9 | import os ; 10 | import testing ; 11 | 12 | # import rules for testing conditional on config file variables 13 | import-search /boost/config/checks ; 14 | import config : requires ; 15 | 16 | project : requirements /boost/dynamic_bitset//boost_dynamic_bitset ; 17 | 18 | test-suite dynamic_bitset : 19 | 20 | [ run dyn_bitset_unit_tests1.cpp : : : /boost/filesystem//boost_filesystem 21 | /boost/system//boost_system ] 22 | [ run dyn_bitset_unit_tests2.cpp : : : /boost/filesystem//boost_filesystem 23 | /boost/system//boost_system ] 24 | [ run dyn_bitset_unit_tests3.cpp : : : /boost/filesystem//boost_filesystem 25 | /boost/system//boost_system ] 26 | [ run dyn_bitset_unit_tests4.cpp : : : /boost/filesystem//boost_filesystem 27 | /boost/system//boost_system ] 28 | [ run test_ambiguous_set.cpp ] 29 | [ run test_lowest_bit.cpp ] 30 | 31 | [ run test_boost_hash.cpp ] 32 | [ run test_std_hash.cpp : : : [ requires cxx11_hdr_unordered_set ] ] 33 | 34 | [ compile-fail test_std_hash.cpp : [ requires cxx11_hdr_unordered_set ] 35 | BOOST_DYNAMIC_BITSET_NO_STD_HASH 36 | : test_std_hash_disabled ] 37 | ; 38 | 39 | # due to https://github.com/boostorg/serialization/issues/108 40 | if ! [ os.environ UBSAN_OPTIONS ] 41 | { 42 | test-suite dynamic_bitset_serialization : 43 | 44 | [ run dyn_bitset_unit_tests5.cpp 45 | : : : _SCL_SECURE_NO_WARNINGS=1 46 | /boost/filesystem//boost_filesystem 47 | /boost/serialization//boost_serialization 48 | /boost/system//boost_system ] 49 | ; 50 | } 51 | -------------------------------------------------------------------------------- /test/bitset_test.hpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006, 2008 Gennaro Prota 4 | // Copyright (c) 2014 Ahmed Charles 5 | // Copyright (c) 2014 Riccardo Marcangelo 6 | // Copyright (c) 2018 Evgeny Shulgin 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. 9 | // (See accompanying file LICENSE_1_0.txt or copy at 10 | // http://www.boost.org/LICENSE_1_0.txt) 11 | // 12 | // ----------------------------------------------------------- 13 | 14 | #ifndef BOOST_BITSET_TEST_HPP_GP_20040319 15 | #define BOOST_BITSET_TEST_HPP_GP_20040319 16 | 17 | #include 18 | #if !defined (BOOST_NO_STD_LOCALE) 19 | # include 20 | #endif 21 | 22 | #include 23 | #include // used for operator<< 24 | #include // for (basic_string and) getline() 25 | #include // for std::min 26 | #include // is sometimes macro-guarded :-( 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | template 34 | inline bool nth_bit(Block num, std::size_t n) 35 | { 36 | #ifndef NDEBUG 37 | #ifdef BOOST_BORLANDC 38 | // Borland deduces Block as a const qualified type, 39 | // and thus finds numeric_limits to be zero :( 40 | // (though not directly relevant here, see also 41 | // lib issue 559) 42 | int block_width = sizeof(Block) * CHAR_BIT; 43 | #else 44 | int block_width = std::numeric_limits::digits; 45 | #endif 46 | assert(n < (std::size_t) block_width); 47 | #endif 48 | 49 | return (num >> n) & 1; 50 | } 51 | 52 | // A long, 'irregular', string useful for various tests 53 | std::string get_long_string() 54 | { 55 | const char * const p = 56 | // 6 5 4 3 2 1 57 | // 3210987654321098765432109876543210987654321098765432109876543210 58 | "1110011100011110000011110000011111110000000000000110101110000000" 59 | "1010101000011100011101010111110000101011111000001111100011100011" 60 | "0000000110000001000000111100000111100010101111111000000011100011" 61 | "1111111111111111111111111111111111111111111111111111111111111100" 62 | "1000001100000001111111111111110000000011111000111100001010100000" 63 | "101000111100011010101110011011000000010"; 64 | 65 | return std::string(p); 66 | } 67 | 68 | class scoped_temp_file 69 | { 70 | public: 71 | scoped_temp_file() 72 | : m_path(boost::filesystem::unique_path()) 73 | { 74 | } 75 | 76 | ~scoped_temp_file() 77 | { 78 | boost::filesystem::remove(m_path); 79 | } 80 | 81 | const boost::filesystem::path& path() const 82 | { 83 | return m_path; 84 | } 85 | 86 | private: 87 | boost::filesystem::path m_path; 88 | }; 89 | 90 | #if defined BOOST_OLD_IOSTREAMS || defined BOOST_NO_STD_LOCALE 91 | template 92 | bool is_one_or_zero(const Stream & /*s*/, char c) 93 | { 94 | return c == '1' || c == '0'; 95 | } 96 | template 97 | bool is_white_space(const Stream & /*s*/, char c) 98 | { 99 | return std::isspace(c); 100 | } 101 | #else 102 | template 103 | bool is_one_or_zero(const Stream& s, Ch c) 104 | { 105 | typedef typename Stream::traits_type Tr; 106 | const Ch zero = s.widen('0'); 107 | const Ch one = s.widen('1'); 108 | 109 | return Tr::eq(c, one) || Tr::eq(c, zero); 110 | } 111 | template 112 | bool is_white_space(const Stream & s, Ch c) 113 | { 114 | // NOTE: the using directive is to satisfy Borland 5.6.4 115 | // with its own library (STLport), which doesn't 116 | // like std::isspace(c, loc) 117 | using namespace std; 118 | return isspace(c, s.getloc()); 119 | } 120 | #endif // defined BOOST_OLD_IOSTREAMS 121 | 122 | 123 | template 124 | bool has_flags(const Stream& s, std::ios::iostate flags) 125 | { 126 | return (s.rdstate() & flags) != std::ios::goodbit; 127 | } 128 | 129 | 130 | // constructors 131 | // default (can't do this generically) 132 | 133 | template 134 | struct bitset_test { 135 | 136 | typedef typename Bitset::block_type Block; 137 | BOOST_STATIC_CONSTANT(int, bits_per_block = Bitset::bits_per_block); 138 | 139 | // from unsigned long 140 | // 141 | // Note: this is templatized so that we check that the do-the-right-thing 142 | // constructor dispatch is working correctly. 143 | // 144 | template 145 | static void from_unsigned_long(NumBits num_bits, Value num) 146 | { 147 | // An object of size sz = num_bits is constructed: 148 | // - the first m bit positions are initialized to the corresponding 149 | // bit values in num (m being the smaller of sz and ulong_width) 150 | // 151 | // - any remaining bit positions are initialized to zero 152 | // 153 | 154 | Bitset b(static_cast(num_bits), static_cast(num)); 155 | 156 | // OK, we can now cast to size_type 157 | typedef typename Bitset::size_type size_type; 158 | const size_type sz = static_cast(num_bits); 159 | 160 | BOOST_TEST(b.size() == sz); 161 | 162 | const std::size_t ulong_width = std::numeric_limits::digits; 163 | size_type m = sz; 164 | if (ulong_width < sz) 165 | m = ulong_width; 166 | 167 | size_type i = 0; 168 | for ( ; i < m; ++i) 169 | BOOST_TEST(b.test(i) == nth_bit(static_cast(num), i)); 170 | for ( ; i < sz; ++i) 171 | BOOST_TEST(b.test(i) == 0); 172 | } 173 | 174 | // from string 175 | // 176 | // Note: The corresponding function in dynamic_bitset (constructor 177 | // from a string) has several default arguments. Actually we don't 178 | // test the correct working of those defaults here (except for the 179 | // default of num_bits). I'm not sure what to do in this regard. 180 | // 181 | // Note2: the default argument expression for num_bits doesn't use 182 | // static_cast, to avoid a gcc 2.95.3 'sorry, not implemented' 183 | // 184 | template 185 | static void from_string(const std::basic_string& str, 186 | std::size_t pos, 187 | std::size_t max_char, 188 | std::size_t num_bits = (std::size_t)(-1)) 189 | { 190 | 191 | std::size_t rlen = (std::min)(max_char, str.size() - pos); 192 | 193 | // The resulting size N of the bitset is num_bits, if 194 | // that is different from the default arg, rlen otherwise. 195 | // Put M = the smaller of N and rlen, then character 196 | // position pos + M - 1 corresponds to bit position zero. 197 | // Subsequent decreasing character positions correspond to 198 | // increasing bit positions. 199 | 200 | const bool size_upon_string = num_bits == (std::size_t)(-1); 201 | Bitset b = size_upon_string ? 202 | Bitset(str, pos, max_char) 203 | : Bitset(str, pos, max_char, num_bits); 204 | 205 | const std::size_t actual_size = size_upon_string? rlen : num_bits; 206 | BOOST_TEST(b.size() == actual_size); 207 | std::size_t m = (std::min)(num_bits, rlen); 208 | std::size_t j; 209 | for (j = 0; j < m; ++j) 210 | BOOST_TEST(b[j] == (str[pos + m - 1 - j] == '1')); 211 | // If M < N, remaining bit positions are zero 212 | for (; j < actual_size; ++j) 213 | BOOST_TEST(b[j] == 0); 214 | 215 | 216 | } 217 | 218 | static void to_block_range(const Bitset & b /*, BlockOutputIterator result*/) 219 | { 220 | typedef typename Bitset::size_type size_type; 221 | 222 | Block sentinel = 0xF0; 223 | int s = 8; // number of sentinels (must be *even*) 224 | int offset = s/2; 225 | std::vector v(b.num_blocks() + s, sentinel); 226 | 227 | boost::to_block_range(b, v.begin() + offset); 228 | 229 | assert(v.size() >= (size_type)s && (s >= 2) && (s % 2 == 0)); 230 | // check sentinels at both ends 231 | for(int i = 0; i < s/2; ++i) { 232 | BOOST_TEST(v[i] == sentinel); 233 | BOOST_TEST(v[v.size()-1-i] == sentinel); 234 | } 235 | 236 | typename std::vector::const_iterator p = v.begin() + offset; 237 | for(size_type n = 0; n < b.num_blocks(); ++n, ++p) { 238 | typename Bitset::block_width_type i = 0; 239 | for(; i < bits_per_block; ++i) { 240 | size_type bit = n * bits_per_block + i; 241 | BOOST_TEST(nth_bit(*p, i) == (bit < b.size()? b[bit] : 0)); 242 | } 243 | } 244 | } 245 | 246 | // TODO from_block_range (below) should be splitted 247 | 248 | // PRE: std::equal(first1, last1, first2) == true 249 | static void from_block_range(const std::vector& blocks) 250 | { 251 | { // test constructor from block range 252 | Bitset bset(blocks.begin(), blocks.end()); 253 | std::size_t n = blocks.size(); 254 | for (std::size_t b = 0; b < n; ++b) { 255 | typename Bitset::block_width_type i = 0; 256 | for (; i < bits_per_block; ++i) { 257 | std::size_t bit = b * bits_per_block + i; 258 | BOOST_TEST(bset[bit] == nth_bit(blocks[b], i)); 259 | } 260 | } 261 | BOOST_TEST(bset.size() == n * bits_per_block); 262 | } 263 | { // test boost::from_block_range 264 | const typename Bitset::size_type n = blocks.size(); 265 | Bitset bset(n * bits_per_block); 266 | boost::from_block_range(blocks.begin(), blocks.end(), bset); 267 | for (std::size_t b = 0; b < n; ++b) { 268 | typename Bitset::block_width_type i = 0; 269 | for (; i < bits_per_block; ++i) { 270 | std::size_t bit = b * bits_per_block + i; 271 | BOOST_TEST(bset[bit] == nth_bit(blocks[b], i)); 272 | } 273 | } 274 | BOOST_TEST(n <= bset.num_blocks()); 275 | } 276 | } 277 | 278 | // copy constructor (absent from std::bitset) 279 | static void copy_constructor(const Bitset& b) 280 | { 281 | Bitset copy(b); 282 | BOOST_TEST(b == copy); 283 | 284 | // Changes to the copy do not affect the original 285 | if (b.size() > 0) { 286 | std::size_t pos = copy.size() / 2; 287 | copy.flip(pos); 288 | BOOST_TEST(copy[pos] != b[pos]); 289 | } 290 | } 291 | 292 | // copy assignment operator (absent from std::bitset) 293 | static void copy_assignment_operator(const Bitset& lhs, const Bitset& rhs) 294 | { 295 | Bitset b(lhs); 296 | b = rhs; 297 | b = b; // self assignment check 298 | BOOST_TEST(b == rhs); 299 | 300 | // Changes to the copy do not affect the original 301 | if (b.size() > 0) { 302 | std::size_t pos = b.size() / 2; 303 | b.flip(pos); 304 | BOOST_TEST(b[pos] != rhs[pos]); 305 | } 306 | } 307 | 308 | static void max_size(const Bitset& b) 309 | { 310 | BOOST_TEST(b.max_size() > 0); 311 | } 312 | 313 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 314 | 315 | // move constructor (absent from std::bitset) 316 | static void move_constructor(const Bitset& b) 317 | { 318 | Bitset copy(boost::move(b)); 319 | BOOST_TEST(b == copy); 320 | } 321 | 322 | // move assignment operator (absent from std::bitset) 323 | static void move_assignment_operator(const Bitset& lhs, const Bitset& rhs) 324 | { 325 | Bitset b(lhs); 326 | Bitset c(rhs); 327 | b = boost::move(c); 328 | b = boost::move(b); // self assignment check 329 | BOOST_TEST(b == rhs); 330 | } 331 | 332 | #endif // BOOST_NO_CXX11_RVALUE_REFERENCES 333 | 334 | static void swap(const Bitset& lhs, const Bitset& rhs) 335 | { 336 | // bitsets must be swapped 337 | Bitset copy1(lhs); 338 | Bitset copy2(rhs); 339 | copy1.swap(copy2); 340 | 341 | BOOST_TEST(copy1 == rhs); 342 | BOOST_TEST(copy2 == lhs); 343 | 344 | // references must be stable under a swap 345 | for(typename Bitset::size_type i = 0; i < lhs.size(); ++i) { 346 | Bitset b1(lhs); 347 | Bitset b2(rhs); 348 | typename Bitset::reference ref = b1[i]; 349 | bool x = ref; 350 | if (i < b2.size()) 351 | b2[i] = !x; // make sure b2[i] is different 352 | b1.swap(b2); 353 | BOOST_TEST(b2[i] == x); // now it must be equal.. 354 | b2.flip(i); 355 | BOOST_TEST(ref == b2[i]); // .. and ref must be into b2 356 | BOOST_TEST(ref == !x); 357 | } 358 | 359 | } 360 | 361 | static void resize(const Bitset& lhs) 362 | { 363 | Bitset b(lhs); 364 | 365 | // Test no change in size 366 | b.resize(lhs.size()); 367 | BOOST_TEST(b == lhs); 368 | 369 | // Test increase in size 370 | b.resize(lhs.size() * 2, true); 371 | 372 | std::size_t i; 373 | for (i = 0; i < lhs.size(); ++i) 374 | BOOST_TEST(b[i] == lhs[i]); 375 | for (; i < b.size(); ++i) 376 | BOOST_TEST(b[i] == true); 377 | 378 | // Test decrease in size 379 | b.resize(lhs.size()); 380 | for (i = 0; i < lhs.size(); ++i) 381 | BOOST_TEST(b[i] == lhs[i]); 382 | } 383 | 384 | static void clear(const Bitset& lhs) 385 | { 386 | Bitset b(lhs); 387 | b.clear(); 388 | BOOST_TEST(b.size() == 0); 389 | } 390 | 391 | static void pop_back(const Bitset& lhs) 392 | { 393 | Bitset b(lhs); 394 | b.pop_back(); 395 | BOOST_TEST(b.size() == lhs.size() - 1); 396 | for (std::size_t i = 0; i < b.size(); ++i) 397 | BOOST_TEST(b[i] == lhs[i]); 398 | 399 | b.pop_back(); 400 | BOOST_TEST(b.size() == lhs.size() - 2); 401 | for (std::size_t j = 0; j < b.size(); ++j) 402 | BOOST_TEST(b[j] == lhs[j]); 403 | } 404 | 405 | static void append_bit(const Bitset& lhs) 406 | { 407 | Bitset b(lhs); 408 | b.push_back(true); 409 | BOOST_TEST(b.size() == lhs.size() + 1); 410 | BOOST_TEST(b[b.size() - 1] == true); 411 | for (std::size_t i = 0; i < lhs.size(); ++i) 412 | BOOST_TEST(b[i] == lhs[i]); 413 | 414 | b.push_back(false); 415 | BOOST_TEST(b.size() == lhs.size() + 2); 416 | BOOST_TEST(b[b.size() - 1] == false); 417 | BOOST_TEST(b[b.size() - 2] == true); 418 | for (std::size_t j = 0; j < lhs.size(); ++j) 419 | BOOST_TEST(b[j] == lhs[j]); 420 | } 421 | 422 | static void append_block(const Bitset& lhs) 423 | { 424 | Bitset b(lhs); 425 | Block value(128); 426 | b.append(value); 427 | BOOST_TEST(b.size() == lhs.size() + bits_per_block); 428 | for (typename Bitset::block_width_type i = 0; i < bits_per_block; ++i) 429 | BOOST_TEST(b[lhs.size() + i] == bool((value >> i) & 1)); 430 | } 431 | 432 | static void append_block_range(const Bitset& lhs, const std::vector& blocks) 433 | { 434 | Bitset b(lhs), c(lhs); 435 | b.append(blocks.begin(), blocks.end()); 436 | for (typename std::vector::const_iterator i = blocks.begin(); 437 | i != blocks.end(); ++i) 438 | c.append(*i); 439 | BOOST_TEST(b == c); 440 | } 441 | 442 | // operator[] and reference members 443 | // PRE: b[i] == bit_vec[i] 444 | static void operator_bracket(const Bitset& lhs, const std::vector& bit_vec) 445 | { 446 | Bitset b(lhs); 447 | std::size_t i, j, k; 448 | 449 | // x = b[i] 450 | // x = ~b[i] 451 | for (i = 0; i < b.size(); ++i) { 452 | bool x = b[i]; 453 | BOOST_TEST(x == bit_vec[i]); 454 | x = ~b[i]; 455 | BOOST_TEST(x == !bit_vec[i]); 456 | } 457 | Bitset prev(b); 458 | 459 | // b[i] = x 460 | for (j = 0; j < b.size(); ++j) { 461 | bool x = !prev[j]; 462 | b[j] = x; 463 | for (k = 0; k < b.size(); ++k) 464 | if (j == k) 465 | BOOST_TEST(b[k] == x); 466 | else 467 | BOOST_TEST(b[k] == prev[k]); 468 | b[j] = prev[j]; 469 | } 470 | b.flip(); 471 | 472 | // b[i] = b[j] 473 | for (i = 0; i < b.size(); ++i) { 474 | b[i] = prev[i]; 475 | for (j = 0; j < b.size(); ++j) { 476 | if (i == j) 477 | BOOST_TEST(b[j] == prev[j]); 478 | else 479 | BOOST_TEST(b[j] == !prev[j]); 480 | } 481 | b[i] = !prev[i]; 482 | } 483 | 484 | // b[i].flip() 485 | for (i = 0; i < b.size(); ++i) { 486 | b[i].flip(); 487 | for (j = 0; j < b.size(); ++j) { 488 | if (i == j) 489 | BOOST_TEST(b[j] == prev[j]); 490 | else 491 | BOOST_TEST(b[j] == !prev[j]); 492 | } 493 | b[i].flip(); 494 | } 495 | } 496 | 497 | //=========================================================================== 498 | // bitwise operators 499 | 500 | // bitwise and assignment 501 | 502 | // PRE: b.size() == rhs.size() 503 | static void and_assignment(const Bitset& b, const Bitset& rhs) 504 | { 505 | Bitset lhs(b); 506 | Bitset prev(lhs); 507 | lhs &= rhs; 508 | // Clears each bit in lhs for which the corresponding bit in rhs is 509 | // clear, and leaves all other bits unchanged. 510 | for (std::size_t I = 0; I < lhs.size(); ++I) 511 | if (rhs[I] == 0) 512 | BOOST_TEST(lhs[I] == 0); 513 | else 514 | BOOST_TEST(lhs[I] == prev[I]); 515 | } 516 | 517 | // PRE: b.size() == rhs.size() 518 | static void or_assignment(const Bitset& b, const Bitset& rhs) 519 | { 520 | Bitset lhs(b); 521 | Bitset prev(lhs); 522 | lhs |= rhs; 523 | // Sets each bit in lhs for which the corresponding bit in rhs is set, and 524 | // leaves all other bits unchanged. 525 | for (std::size_t I = 0; I < lhs.size(); ++I) 526 | if (rhs[I] == 1) 527 | BOOST_TEST(lhs[I] == 1); 528 | else 529 | BOOST_TEST(lhs[I] == prev[I]); 530 | } 531 | 532 | // PRE: b.size() == rhs.size() 533 | static void xor_assignment(const Bitset& b, const Bitset& rhs) 534 | { 535 | Bitset lhs(b); 536 | Bitset prev(lhs); 537 | lhs ^= rhs; 538 | // Flips each bit in lhs for which the corresponding bit in rhs is set, 539 | // and leaves all other bits unchanged. 540 | for (std::size_t I = 0; I < lhs.size(); ++I) 541 | if (rhs[I] == 1) 542 | BOOST_TEST(lhs[I] == !prev[I]); 543 | else 544 | BOOST_TEST(lhs[I] == prev[I]); 545 | } 546 | 547 | // PRE: b.size() == rhs.size() 548 | static void sub_assignment(const Bitset& b, const Bitset& rhs) 549 | { 550 | Bitset lhs(b); 551 | Bitset prev(lhs); 552 | lhs -= rhs; 553 | // Resets each bit in lhs for which the corresponding bit in rhs is set, 554 | // and leaves all other bits unchanged. 555 | for (std::size_t I = 0; I < lhs.size(); ++I) 556 | if (rhs[I] == 1) 557 | BOOST_TEST(lhs[I] == 0); 558 | else 559 | BOOST_TEST(lhs[I] == prev[I]); 560 | } 561 | 562 | static void shift_left_assignment(const Bitset& b, std::size_t pos) 563 | { 564 | Bitset lhs(b); 565 | Bitset prev(lhs); 566 | lhs <<= pos; 567 | // Replaces each bit at position I in lhs with the following value: 568 | // - If I < pos, the new value is zero 569 | // - If I >= pos, the new value is the previous value of the bit at 570 | // position I - pos 571 | for (std::size_t I = 0; I < lhs.size(); ++I) 572 | if (I < pos) 573 | BOOST_TEST(lhs[I] == 0); 574 | else 575 | BOOST_TEST(lhs[I] == prev[I - pos]); 576 | } 577 | 578 | static void shift_right_assignment(const Bitset& b, std::size_t pos) 579 | { 580 | Bitset lhs(b); 581 | Bitset prev(lhs); 582 | lhs >>= pos; 583 | // Replaces each bit at position I in lhs with the following value: 584 | // - If pos >= N - I, the new value is zero 585 | // - If pos < N - I, the new value is the previous value of the bit at 586 | // position I + pos 587 | std::size_t N = lhs.size(); 588 | for (std::size_t I = 0; I < N; ++I) 589 | if (pos >= N - I) 590 | BOOST_TEST(lhs[I] == 0); 591 | else 592 | BOOST_TEST(lhs[I] == prev[I + pos]); 593 | } 594 | 595 | 596 | static void set_all(const Bitset& b) 597 | { 598 | Bitset lhs(b); 599 | lhs.set(); 600 | for (std::size_t I = 0; I < lhs.size(); ++I) 601 | BOOST_TEST(lhs[I] == 1); 602 | } 603 | 604 | static void set_one(const Bitset& b, std::size_t pos, bool value) 605 | { 606 | Bitset lhs(b); 607 | std::size_t N = lhs.size(); 608 | if (pos < N) { 609 | Bitset prev(lhs); 610 | // Stores a new value in the bit at position pos in lhs. 611 | lhs.set(pos, value); 612 | BOOST_TEST(lhs[pos] == value); 613 | 614 | // All other values of lhs remain unchanged 615 | for (std::size_t I = 0; I < N; ++I) 616 | if (I != pos) 617 | BOOST_TEST(lhs[I] == prev[I]); 618 | } else { 619 | // Not in range, doesn't satisfy precondition. 620 | } 621 | } 622 | 623 | static void set_segment(const Bitset& b, std::size_t pos, 624 | std::size_t len, bool value) 625 | { 626 | Bitset lhs(b); 627 | std::size_t N = lhs.size(); 628 | Bitset prev(lhs); 629 | lhs.set(pos, len, value); 630 | for (std::size_t I = 0; I < N; ++I) 631 | { 632 | if (I < pos || I >= pos + len) 633 | BOOST_TEST(lhs[I] == prev[I]); 634 | else 635 | BOOST_TEST(lhs[I] == value); 636 | } 637 | } 638 | 639 | static void reset_all(const Bitset& b) 640 | { 641 | Bitset lhs(b); 642 | // Resets all bits in lhs 643 | lhs.reset(); 644 | for (std::size_t I = 0; I < lhs.size(); ++I) 645 | BOOST_TEST(lhs[I] == 0); 646 | } 647 | 648 | static void reset_one(const Bitset& b, std::size_t pos) 649 | { 650 | Bitset lhs(b); 651 | std::size_t N = lhs.size(); 652 | if (pos < N) { 653 | Bitset prev(lhs); 654 | lhs.reset(pos); 655 | // Resets the bit at position pos in lhs 656 | BOOST_TEST(lhs[pos] == 0); 657 | 658 | // All other values of lhs remain unchanged 659 | for (std::size_t I = 0; I < N; ++I) 660 | if (I != pos) 661 | BOOST_TEST(lhs[I] == prev[I]); 662 | } else { 663 | // Not in range, doesn't satisfy precondition. 664 | } 665 | } 666 | 667 | static void reset_segment(const Bitset& b, std::size_t pos, 668 | std::size_t len) 669 | { 670 | Bitset lhs(b); 671 | std::size_t N = lhs.size(); 672 | Bitset prev(lhs); 673 | lhs.reset(pos, len); 674 | for (std::size_t I = 0; I < N; ++I) 675 | { 676 | if (I < pos || I >= pos + len) 677 | BOOST_TEST(lhs[I] == prev[I]); 678 | else 679 | BOOST_TEST(!lhs[I]); 680 | } 681 | } 682 | 683 | static void operator_flip(const Bitset& b) 684 | { 685 | Bitset lhs(b); 686 | Bitset x(lhs); 687 | BOOST_TEST(~lhs == x.flip()); 688 | } 689 | 690 | static void flip_all(const Bitset& b) 691 | { 692 | Bitset lhs(b); 693 | std::size_t N = lhs.size(); 694 | Bitset prev(lhs); 695 | lhs.flip(); 696 | // Toggles all the bits in lhs 697 | for (std::size_t I = 0; I < N; ++I) 698 | BOOST_TEST(lhs[I] == !prev[I]); 699 | } 700 | 701 | static void flip_one(const Bitset& b, std::size_t pos) 702 | { 703 | Bitset lhs(b); 704 | std::size_t N = lhs.size(); 705 | if (pos < N) { 706 | Bitset prev(lhs); 707 | lhs.flip(pos); 708 | // Toggles the bit at position pos in lhs 709 | BOOST_TEST(lhs[pos] == !prev[pos]); 710 | 711 | // All other values of lhs remain unchanged 712 | for (std::size_t I = 0; I < N; ++I) 713 | if (I != pos) 714 | BOOST_TEST(lhs[I] == prev[I]); 715 | } else { 716 | // Not in range, doesn't satisfy precondition. 717 | } 718 | } 719 | 720 | static void flip_segment(const Bitset& b, std::size_t pos, 721 | std::size_t len) 722 | { 723 | Bitset lhs(b); 724 | std::size_t N = lhs.size(); 725 | Bitset prev(lhs); 726 | lhs.flip(pos, len); 727 | for (std::size_t I = 0; I < N; ++I) 728 | { 729 | if (I < pos || I >= pos + len) 730 | BOOST_TEST(lhs[I] == prev[I]); 731 | else 732 | BOOST_TEST(lhs[I] != prev[I]); 733 | } 734 | } 735 | 736 | // empty 737 | static void empty(const Bitset& b) 738 | { 739 | BOOST_TEST(b.empty() == (b.size() == 0)); 740 | } 741 | 742 | // to_ulong() 743 | static void to_ulong(const Bitset& lhs) 744 | { 745 | typedef unsigned long result_type; 746 | std::size_t n = std::numeric_limits::digits; 747 | std::size_t sz = lhs.size(); 748 | 749 | bool will_overflow = false; 750 | for (std::size_t i = n; i < sz; ++i) { 751 | if (lhs.test(i) != 0) { 752 | will_overflow = true; 753 | break; 754 | } 755 | } 756 | if (will_overflow) { 757 | try { 758 | (void)lhs.to_ulong(); 759 | BOOST_TEST(false); // It should have thrown an exception 760 | } catch (std::overflow_error & ex) { 761 | // Good! 762 | BOOST_TEST(!!ex.what()); 763 | } catch (...) { 764 | BOOST_TEST(false); // threw the wrong exception 765 | } 766 | } else { 767 | result_type num = lhs.to_ulong(); 768 | // Be sure the number is right 769 | if (sz == 0) 770 | BOOST_TEST(num == 0); 771 | else { 772 | for (std::size_t i = 0; i < sz; ++i) 773 | BOOST_TEST(lhs[i] == (i < n ? nth_bit(num, i) : 0)); 774 | } 775 | } 776 | } 777 | 778 | // to_string() 779 | static void to_string(const Bitset& b) 780 | { 781 | std::string str; 782 | boost::to_string(b, str); 783 | BOOST_TEST(str.size() == b.size()); 784 | for (std::size_t i = 0; i < b.size(); ++i) 785 | BOOST_TEST(str[b.size() - 1 - i] ==(b.test(i)? '1':'0')); 786 | } 787 | 788 | static void count(const Bitset& b) 789 | { 790 | std::size_t c = b.count(); 791 | std::size_t actual = 0; 792 | for (std::size_t i = 0; i < b.size(); ++i) 793 | if (b[i]) 794 | ++actual; 795 | BOOST_TEST(c == actual); 796 | } 797 | 798 | static void size(const Bitset& b) 799 | { 800 | BOOST_TEST(Bitset(b).set().count() == b.size()); 801 | } 802 | 803 | static void capacity_test_one(const Bitset& lhs) 804 | { 805 | //empty bitset 806 | Bitset b(lhs); 807 | BOOST_TEST(b.capacity() == 0); 808 | } 809 | 810 | static void capacity_test_two(const Bitset& lhs) 811 | { 812 | //bitset constructed with size "100" 813 | Bitset b(lhs); 814 | BOOST_TEST(b.capacity() >= 100); 815 | b.resize(200); 816 | BOOST_TEST(b.capacity() >= 200); 817 | } 818 | 819 | static void reserve_test_one(const Bitset& lhs) 820 | { 821 | //empty bitset 822 | Bitset b(lhs); 823 | b.reserve(16); 824 | BOOST_TEST(b.capacity() >= 16); 825 | } 826 | 827 | static void reserve_test_two(const Bitset& lhs) 828 | { 829 | //bitset constructed with size "100" 830 | Bitset b(lhs); 831 | BOOST_TEST(b.capacity() >= 100); 832 | b.reserve(60); 833 | BOOST_TEST(b.size() == 100); 834 | BOOST_TEST(b.capacity() >= 100); 835 | b.reserve(160); 836 | BOOST_TEST(b.size() == 100); 837 | BOOST_TEST(b.capacity() >= 160); 838 | } 839 | 840 | static void shrink_to_fit_test_one(const Bitset& lhs) 841 | { 842 | //empty bitset 843 | Bitset b(lhs); 844 | b.shrink_to_fit(); 845 | BOOST_TEST(b.size() == 0); 846 | BOOST_TEST(b.capacity() == 0); 847 | } 848 | 849 | static void shrink_to_fit_test_two(const Bitset& lhs) 850 | { 851 | //bitset constructed with size "100" 852 | Bitset b(lhs); 853 | b.shrink_to_fit(); 854 | BOOST_TEST(b.capacity() >= 100); 855 | BOOST_TEST(b.size() == 100); 856 | b.reserve(200); 857 | BOOST_TEST(b.capacity() >= 200); 858 | BOOST_TEST(b.size() == 100); 859 | b.shrink_to_fit(); 860 | BOOST_TEST(b.capacity() < 200); 861 | BOOST_TEST(b.size() == 100); 862 | } 863 | 864 | static void all(const Bitset& b) 865 | { 866 | BOOST_TEST(b.all() == (b.count() == b.size())); 867 | bool result = true; 868 | for(std::size_t i = 0; i < b.size(); ++i) 869 | if(!b[i]) { 870 | result = false; 871 | break; 872 | } 873 | BOOST_TEST(b.all() == result); 874 | } 875 | 876 | static void any(const Bitset& b) 877 | { 878 | BOOST_TEST(b.any() == (b.count() != 0)); 879 | bool result = false; 880 | for(std::size_t i = 0; i < b.size(); ++i) 881 | if(b[i]) { 882 | result = true; 883 | break; 884 | } 885 | BOOST_TEST(b.any() == result); 886 | } 887 | 888 | static void none(const Bitset& b) 889 | { 890 | bool result = true; 891 | for(std::size_t i = 0; i < b.size(); ++i) { 892 | if(b[i]) { 893 | result = false; 894 | break; 895 | } 896 | } 897 | BOOST_TEST(b.none() == result); 898 | 899 | // sanity 900 | BOOST_TEST(b.none() == !b.any()); 901 | BOOST_TEST(b.none() == (b.count() == 0)); 902 | } 903 | 904 | static void subset(const Bitset& a, const Bitset& b) 905 | { 906 | BOOST_TEST(a.size() == b.size()); // PRE 907 | 908 | bool is_subset = true; 909 | if (b.size()) { // could use b.any() but let's be safe 910 | for(std::size_t i = 0; i < a.size(); ++i) { 911 | if(a.test(i) && !b.test(i)) { 912 | is_subset = false; 913 | break; 914 | } 915 | } 916 | } 917 | else { 918 | // sanity 919 | BOOST_TEST(a.count() == 0); 920 | BOOST_TEST(a.any() == false); 921 | 922 | //is_subset = (a.any() == false); 923 | } 924 | 925 | BOOST_TEST(a.is_subset_of(b) == is_subset); 926 | } 927 | 928 | static void proper_subset(const Bitset& a, const Bitset& b) 929 | { 930 | // PRE: a.size() == b.size() 931 | BOOST_TEST(a.size() == b.size()); 932 | 933 | bool is_proper = false; 934 | 935 | if (b.size() != 0) { 936 | 937 | // check it's a subset 938 | subset(a, b); 939 | 940 | // is it proper? 941 | for (std::size_t i = 0; i < a.size(); ++i) { 942 | if (!a.test(i) && b.test(i)) { 943 | is_proper = true; 944 | // sanity 945 | BOOST_TEST(a.count() < b.count()); 946 | BOOST_TEST(b.any()); 947 | } 948 | } 949 | } 950 | 951 | BOOST_TEST(a.is_proper_subset_of(b) == is_proper); 952 | if (is_proper) 953 | BOOST_TEST(b.is_proper_subset_of(a) != is_proper);// antisymmetry 954 | } 955 | 956 | static void intersects(const Bitset& a, const Bitset& b) 957 | { 958 | bool have_intersection = false; 959 | 960 | typename Bitset::size_type m = a.size() < b.size() ? a.size() : b.size(); 961 | for(typename Bitset::size_type i = 0; i < m && !have_intersection; ++i) 962 | if(a[i] == true && b[i] == true) 963 | have_intersection = true; 964 | 965 | BOOST_TEST(a.intersects(b) == have_intersection); 966 | // also check commutativity 967 | BOOST_TEST(b.intersects(a) == have_intersection); 968 | } 969 | 970 | static void find_first(const Bitset& b, typename Bitset::size_type offset = 0) 971 | { 972 | // find first non-null bit from offset onwards, if any 973 | typename Bitset::size_type i = offset; 974 | while (i < b.size() && b[i] == 0) 975 | ++i; 976 | 977 | if (i >= b.size()) 978 | BOOST_TEST(b.find_first(offset) == Bitset::npos); // not found; 979 | else { 980 | BOOST_TEST(b.find_first(offset) == i); 981 | BOOST_TEST(b.test(i) == true); 982 | } 983 | } 984 | 985 | static void find_pos(const Bitset& b, typename Bitset::size_type pos) 986 | { 987 | find_first(b, pos); 988 | BOOST_TEST(next_bit_on(b, pos) == b.find_next(pos)); 989 | } 990 | 991 | static void operator_equal(const Bitset& a, const Bitset& b) 992 | { 993 | if (a == b) { 994 | for (std::size_t I = 0; I < a.size(); ++I) 995 | BOOST_TEST(a[I] == b[I]); 996 | } else { 997 | if (a.size() == b.size()) { 998 | bool diff = false; 999 | for (std::size_t I = 0; I < a.size(); ++I) 1000 | if (a[I] != b[I]) { 1001 | diff = true; 1002 | break; 1003 | } 1004 | BOOST_TEST(diff); 1005 | } 1006 | } 1007 | } 1008 | 1009 | static void operator_not_equal(const Bitset& a, const Bitset& b) 1010 | { 1011 | if (a != b) { 1012 | if (a.size() == b.size()) { 1013 | bool diff = false; 1014 | for (std::size_t I = 0; I < a.size(); ++I) 1015 | if (a[I] != b[I]) { 1016 | diff = true; 1017 | break; 1018 | } 1019 | BOOST_TEST(diff); 1020 | } 1021 | } else { 1022 | for (std::size_t I = 0; I < a.size(); ++I) 1023 | BOOST_TEST(a[I] == b[I]); 1024 | } 1025 | } 1026 | 1027 | static bool less_than(const Bitset& a, const Bitset& b) 1028 | { 1029 | 1030 | typedef BOOST_DEDUCED_TYPENAME Bitset::size_type size_type; 1031 | 1032 | size_type asize(a.size()); 1033 | size_type bsize(b.size()); 1034 | 1035 | if (!bsize) 1036 | { 1037 | return false; 1038 | } 1039 | else if (!asize) 1040 | { 1041 | return true; 1042 | } 1043 | else 1044 | { 1045 | 1046 | // Compare from most significant to least. 1047 | 1048 | size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize)); 1049 | size_type I; 1050 | for (I = 0; I < leqsize; ++I,--asize,--bsize) 1051 | { 1052 | 1053 | size_type i = asize-1; 1054 | size_type j = bsize-1; 1055 | 1056 | if (a[i] < b[j]) 1057 | return true; 1058 | else if (a[i] > b[j]) 1059 | return false; 1060 | // if (a[i] = b[j]) skip to next 1061 | } 1062 | return (a.size() < b.size()); 1063 | } 1064 | } 1065 | 1066 | static typename Bitset::size_type next_bit_on(const Bitset& b, typename Bitset::size_type prev) 1067 | { 1068 | // helper function for find_next() 1069 | // 1070 | 1071 | if (b.none() == true || prev == Bitset::npos) 1072 | return Bitset::npos; 1073 | 1074 | ++prev; 1075 | 1076 | if (prev >= b.size()) 1077 | return Bitset::npos; 1078 | 1079 | typename Bitset::size_type i = prev; 1080 | while (i < b.size() && b[i] == 0) 1081 | ++i; 1082 | 1083 | return i==b.size() ? Bitset::npos : i; 1084 | 1085 | } 1086 | 1087 | static void operator_less_than(const Bitset& a, const Bitset& b) 1088 | { 1089 | if (less_than(a, b)) 1090 | BOOST_TEST(a < b); 1091 | else 1092 | BOOST_TEST(!(a < b)); 1093 | } 1094 | 1095 | static void operator_greater_than(const Bitset& a, const Bitset& b) 1096 | { 1097 | if (less_than(a, b) || a == b) 1098 | BOOST_TEST(!(a > b)); 1099 | else 1100 | BOOST_TEST(a > b); 1101 | } 1102 | 1103 | static void operator_less_than_eq(const Bitset& a, const Bitset& b) 1104 | { 1105 | if (less_than(a, b) || a == b) 1106 | BOOST_TEST(a <= b); 1107 | else 1108 | BOOST_TEST(!(a <= b)); 1109 | } 1110 | 1111 | static void operator_greater_than_eq(const Bitset& a, const Bitset& b) 1112 | { 1113 | if (less_than(a, b)) 1114 | BOOST_TEST(!(a >= b)); 1115 | else 1116 | BOOST_TEST(a >= b); 1117 | } 1118 | 1119 | static void test_bit(const Bitset& b, std::size_t pos) 1120 | { 1121 | Bitset lhs(b); 1122 | std::size_t N = lhs.size(); 1123 | if (pos < N) { 1124 | BOOST_TEST(lhs.test(pos) == lhs[pos]); 1125 | } else { 1126 | // Not in range, doesn't satisfy precondition. 1127 | } 1128 | } 1129 | 1130 | static void test_set_bit(const Bitset& b, std::size_t pos, bool value) 1131 | { 1132 | Bitset lhs(b); 1133 | std::size_t N = lhs.size(); 1134 | if (pos < N) { 1135 | Bitset prev(lhs); 1136 | // Stores a new value in the bit at position pos in lhs. 1137 | BOOST_TEST(lhs.test_set(pos, value) == prev[pos]); 1138 | BOOST_TEST(lhs[pos] == value); 1139 | 1140 | // All other values of lhs remain unchanged 1141 | for (std::size_t I = 0; I < N; ++I) 1142 | if (I != pos) 1143 | BOOST_TEST(lhs[I] == prev[I]); 1144 | } else { 1145 | // Not in range, doesn't satisfy precondition. 1146 | } 1147 | } 1148 | 1149 | static void operator_shift_left(const Bitset& lhs, std::size_t pos) 1150 | { 1151 | Bitset x(lhs); 1152 | BOOST_TEST((lhs << pos) == (x <<= pos)); 1153 | } 1154 | 1155 | static void operator_shift_right(const Bitset& lhs, std::size_t pos) 1156 | { 1157 | Bitset x(lhs); 1158 | BOOST_TEST((lhs >> pos) == (x >>= pos)); 1159 | } 1160 | 1161 | static void at(const Bitset& lhs, const std::vector& bit_vec) 1162 | { 1163 | Bitset b(lhs); 1164 | std::size_t i, j, k; 1165 | 1166 | // x = b.at(i) 1167 | // x = ~b.at(i) 1168 | for (i = 0; i < b.size(); ++i) 1169 | { 1170 | bool x = b.at(i); 1171 | BOOST_TEST(x == bit_vec.at(i)); 1172 | x = ~b.at(i); 1173 | BOOST_TEST(x == !bit_vec.at(i)); 1174 | } 1175 | Bitset prev(b); 1176 | 1177 | // b.at(i) = x 1178 | for (j = 0; j < b.size(); ++j) 1179 | { 1180 | bool x = !prev.at(j); 1181 | b.at(j) = x; 1182 | for (k = 0; k < b.size(); ++k) 1183 | if (j == k) 1184 | BOOST_TEST(b.at(k) == x); 1185 | else 1186 | BOOST_TEST(b.at(k) == prev.at(k)); 1187 | b.at(j) = prev.at(j); 1188 | } 1189 | b.flip(); 1190 | 1191 | // b.at(i) = b.at(j) 1192 | for (i = 0; i < b.size(); ++i) 1193 | { 1194 | b.at(i) = prev.at(i); 1195 | for (j = 0; j < b.size(); ++j) 1196 | { 1197 | if (i == j) 1198 | BOOST_TEST(b.at(j) == prev.at(j)); 1199 | else 1200 | BOOST_TEST(b.at(j) == !prev.at(j)); 1201 | } 1202 | b.at(i) = !prev.at(i); 1203 | } 1204 | 1205 | // b.at(i).flip() 1206 | for (i = 0; i < b.size(); ++i) 1207 | { 1208 | b.at(i).flip(); 1209 | for (j = 0; j < b.size(); ++j) 1210 | { 1211 | if (i == j) 1212 | BOOST_TEST(b.at(j) == prev.at(j)); 1213 | else 1214 | BOOST_TEST(b.at(j) == !prev.at(j)); 1215 | } 1216 | b.at(i).flip(); 1217 | } 1218 | 1219 | // b.at(b.size()) 1220 | bool will_out_of_range = false; 1221 | for (i = 0; i <= b.size(); ++i) 1222 | { 1223 | if (i == b.size()) 1224 | { 1225 | will_out_of_range = true; 1226 | break; 1227 | } 1228 | b.at(i); 1229 | } 1230 | if (will_out_of_range) 1231 | { 1232 | try 1233 | { 1234 | b.at(b.size()); 1235 | BOOST_TEST(false); // It should have thrown an exception 1236 | } 1237 | catch (const std::out_of_range& ex) 1238 | { 1239 | // Good! 1240 | BOOST_TEST(!!ex.what()); 1241 | } 1242 | catch (...) 1243 | { 1244 | BOOST_TEST(false); // threw the wrong exception 1245 | } 1246 | } 1247 | } 1248 | 1249 | // operator| 1250 | static 1251 | void operator_or(const Bitset& lhs, const Bitset& rhs) 1252 | { 1253 | Bitset x(lhs); 1254 | BOOST_TEST((lhs | rhs) == (x |= rhs)); 1255 | } 1256 | 1257 | // operator& 1258 | static 1259 | void operator_and(const Bitset& lhs, const Bitset& rhs) 1260 | { 1261 | Bitset x(lhs); 1262 | BOOST_TEST((lhs & rhs) == (x &= rhs)); 1263 | } 1264 | 1265 | // operator^ 1266 | static 1267 | void operator_xor(const Bitset& lhs, const Bitset& rhs) 1268 | { 1269 | Bitset x(lhs); 1270 | BOOST_TEST((lhs ^ rhs) == (x ^= rhs)); 1271 | } 1272 | 1273 | // operator- 1274 | static 1275 | void operator_sub(const Bitset& lhs, const Bitset& rhs) 1276 | { 1277 | Bitset x(lhs); 1278 | BOOST_TEST((lhs - rhs) == (x -= rhs)); 1279 | } 1280 | 1281 | //------------------------------------------------------------------------------ 1282 | // I/O TESTS 1283 | // The following tests assume the results of extraction (i.e.: contents, 1284 | // state and width of is, contents of b) only depend on input (the string 1285 | // str). In other words, they don't consider "unexpected" errors such as 1286 | // stream corruption or out of memory. The reason is simple: if e.g. the 1287 | // stream buffer throws, the stream layer may eat the exception and 1288 | // transform it into a badbit. But we can't trust the stream state here, 1289 | // because one of the things that we want to test is exactly whether it 1290 | // is set correctly. Similarly for insertion. 1291 | // 1292 | // To provide for these cases would require that the test functions know 1293 | // in advance whether the stream buffer and/or allocations will fail, and 1294 | // when; that is, we should write both a special allocator and a special 1295 | // stream buffer capable of throwing "on demand" and pass them here. 1296 | 1297 | // Seems overkill for these kinds of unit tests. 1298 | //------------------------------------------------------------------------- 1299 | 1300 | // operator<<( [basic_]ostream, 1301 | template 1302 | static void stream_inserter(const Bitset & b, 1303 | Stream & s, 1304 | const char * file_name 1305 | ) 1306 | { 1307 | #if defined BOOST_OLD_IOSTREAMS 1308 | typedef char char_type; 1309 | typedef std::string string_type; 1310 | typedef ifstream corresponding_input_stream_type; 1311 | #else 1312 | typedef typename Stream::char_type char_type; 1313 | typedef std::basic_string string_type; 1314 | typedef std::basic_ifstream corresponding_input_stream_type; 1315 | 1316 | std::ios::iostate except = s.exceptions(); 1317 | #endif 1318 | 1319 | typedef typename Bitset::size_type size_type; 1320 | std::streamsize w = s.width(); 1321 | char_type fill_char = s.fill(); 1322 | std::ios::iostate oldstate = s.rdstate(); 1323 | bool stream_was_good = s.good(); 1324 | 1325 | bool did_throw = false; 1326 | try { 1327 | s << b; 1328 | } 1329 | #if defined BOOST_OLD_IOSTREAMS 1330 | catch(...) { 1331 | BOOST_TEST(false); 1332 | } 1333 | #else 1334 | catch (const std::ios_base::failure &) { 1335 | BOOST_TEST((except & s.rdstate()) != 0); 1336 | did_throw = true; 1337 | } catch (...) { 1338 | did_throw = true; 1339 | } 1340 | #endif 1341 | 1342 | BOOST_TEST(did_throw || !stream_was_good || (s.width() == 0)); 1343 | 1344 | if (!stream_was_good) { 1345 | BOOST_TEST(s.good() == false); 1346 | 1347 | // this should actually be oldstate == s.rdstate() 1348 | // but some implementations add badbit in the 1349 | // sentry constructor 1350 | // 1351 | BOOST_TEST((oldstate & s.rdstate()) == oldstate); 1352 | BOOST_TEST(s.width() == w); 1353 | } 1354 | else { 1355 | if(!did_throw) 1356 | BOOST_TEST(s.width() == 0); 1357 | // This test require that os be an output _and_ input stream. 1358 | // Of course dynamic_bitset's operator << doesn't require that. 1359 | 1360 | size_type total_len = w <= 0 || static_cast(w) < b.size()? b.size() : static_cast(w); 1361 | const string_type padding (total_len - b.size(), fill_char); 1362 | string_type expected; 1363 | boost::to_string(b, expected); 1364 | if ((s.flags() & std::ios::adjustfield) != std::ios::left) 1365 | expected = padding + expected; 1366 | else 1367 | expected = expected + padding; 1368 | 1369 | assert(expected.length() == total_len); 1370 | 1371 | // close, and reopen the file stream to verify contents 1372 | s.close(); 1373 | corresponding_input_stream_type is(file_name); 1374 | string_type contents; 1375 | std::getline(is, contents, char_type()); 1376 | BOOST_TEST(contents == expected); 1377 | } 1378 | } 1379 | 1380 | // operator>>( [basic_]istream 1381 | template 1382 | static void stream_extractor(Bitset& b, 1383 | Stream& is, 1384 | String& str 1385 | ) 1386 | { 1387 | // save necessary info then do extraction 1388 | // 1389 | const std::streamsize w = is.width(); 1390 | Bitset a_copy(b); 1391 | bool stream_was_good = is.good(); 1392 | 1393 | bool did_throw = false; 1394 | 1395 | #if defined BOOST_OLD_IOSTREAMS 1396 | bool has_stream_exceptions = false; 1397 | is >> b; 1398 | #else 1399 | const std::ios::iostate except = is.exceptions(); 1400 | bool has_stream_exceptions = true; 1401 | try { 1402 | is >> b; 1403 | } 1404 | catch(const std::ios::failure &) { 1405 | did_throw = true; 1406 | } 1407 | 1408 | // postconditions 1409 | BOOST_TEST(except == is.exceptions()); // paranoid 1410 | #endif 1411 | //------------------------------------------------------------------ 1412 | 1413 | // postconditions 1414 | BOOST_TEST(b.size() <= b.max_size()); 1415 | if(w > 0) 1416 | BOOST_TEST(b.size() <= static_cast(w)); 1417 | 1418 | // throw if and only if required 1419 | if(has_stream_exceptions) { 1420 | const bool exceptional_state = has_flags(is, is.exceptions()); 1421 | BOOST_TEST(exceptional_state == did_throw); 1422 | } 1423 | 1424 | typedef typename String::size_type size_type; 1425 | typedef typename String::value_type Ch; 1426 | size_type after_digits = 0; 1427 | 1428 | if(!stream_was_good) { 1429 | BOOST_TEST(has_flags(is, std::ios::failbit)); 1430 | BOOST_TEST(b == a_copy); 1431 | BOOST_TEST(is.width() == (did_throw ? w : 0)); 1432 | } 1433 | else { 1434 | // stream was good(), parse the string; 1435 | // it may contain three parts, all of which are optional 1436 | // {spaces} {digits} {non-digits} 1437 | // opt opt opt 1438 | // 1439 | // The values of b.max_size() and is.width() may lead to 1440 | // ignore part of the digits, if any. 1441 | 1442 | size_type pos = 0; 1443 | size_type len = str.length(); 1444 | // {spaces} 1445 | for( ; pos < len && is_white_space(is, str[pos]); ++pos) 1446 | {} 1447 | size_type after_spaces = pos; 1448 | // {digits} or part of them 1449 | const typename Bitset::size_type max_digits = 1450 | w > 0 && static_cast(w) < b.max_size() 1451 | ? static_cast(w) : b.max_size(); 1452 | 1453 | for( ; pos < len && (pos - after_spaces) < max_digits; ++pos) { 1454 | if(!is_one_or_zero(is, str[pos])) 1455 | break; 1456 | } 1457 | after_digits = pos; 1458 | size_type num_digits = after_digits - after_spaces; 1459 | 1460 | // eofbit 1461 | if((after_digits == len && max_digits > num_digits )) 1462 | BOOST_TEST(has_flags(is, std::ios::eofbit)); 1463 | else 1464 | BOOST_TEST(!has_flags(is, std::ios::eofbit)); 1465 | 1466 | // failbit <=> there are no digits, except for the library 1467 | // issue explained below. 1468 | // 1469 | if(num_digits == 0) { 1470 | if(after_digits == len && has_stream_exceptions && 1471 | (is.exceptions() & std::ios::eofbit) != std::ios::goodbit) { 1472 | // This is a special case related to library issue 195: 1473 | // reaching eof when skipping whitespaces in the sentry ctor. 1474 | // The resolution says the sentry constructor should set *both* 1475 | // eofbit and failbit; but many implementations deliberately 1476 | // set eofbit only. See for instance: 1477 | // http://gcc.gnu.org/ml/libstdc++/2000-q1/msg00086.html 1478 | // 1479 | BOOST_TEST(did_throw); 1480 | 1481 | } 1482 | else { 1483 | BOOST_TEST(has_flags(is, std::ios::failbit)); 1484 | } 1485 | } 1486 | else 1487 | BOOST_TEST(!has_flags(is, std::ios::failbit)); 1488 | 1489 | 1490 | if(num_digits == 0 && after_digits == len) { 1491 | // The VC6 library has a bug/non-conformity in the sentry 1492 | // constructor. It uses code like 1493 | // // skip whitespaces... 1494 | // int_type _C = rdbuf()->sgetc(); 1495 | // while (!_Tr::eq_int_type(_Tr::eof(), _C) ... 1496 | // 1497 | // For an empty file the while statement is never "entered" 1498 | // and the stream remains in good() state; thus the sentry 1499 | // object gives "true" when converted to bool. This is worse 1500 | // than the case above, because not only failbit is not set, 1501 | // but no bit is set at all, end we end up clearing the 1502 | // bitset though there's nothing in the file to be extracted. 1503 | // Note that the dynamic_bitset docs say a sentry object is 1504 | // constructed and then converted to bool, thus we rely on 1505 | // what the underlying library does. 1506 | // 1507 | #if !defined(BOOST_DINKUMWARE_STDLIB) || (BOOST_DINKUMWARE_STDLIB >= 306) 1508 | BOOST_TEST(b == a_copy); 1509 | #else 1510 | BOOST_TEST(b.empty() == true); 1511 | #endif 1512 | } 1513 | else { 1514 | String sub = str.substr(after_spaces, num_digits); 1515 | BOOST_TEST(b == Bitset(sub)); 1516 | } 1517 | 1518 | // check width 1519 | BOOST_TEST(is.width() == 0 1520 | || (after_digits == len && num_digits == 0 && did_throw)); 1521 | } 1522 | 1523 | 1524 | // clear the stream to allow further reading then 1525 | // retrieve any remaining chars with a single getline() 1526 | is.exceptions(std::ios::goodbit); 1527 | is.clear(); 1528 | String remainder; 1529 | std::getline(is, remainder, Ch()); 1530 | if(stream_was_good) 1531 | BOOST_TEST(remainder == str.substr(after_digits)); 1532 | else 1533 | BOOST_TEST(remainder == str); 1534 | 1535 | } 1536 | 1537 | 1538 | }; 1539 | 1540 | 1541 | 1542 | #endif // include guard 1543 | -------------------------------------------------------------------------------- /test/cmake_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2021-2024 Alexander Grund 2 | # Distributed under the Boost Software License, Version 1.0. 3 | # See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 | 5 | cmake_minimum_required(VERSION 3.5...3.16) 6 | 7 | project(cmake_subdir_test LANGUAGES CXX) 8 | 9 | # Those 2 should work the same 10 | # while using find_package for the installed Boost avoids the need to manually specify dependencies 11 | if(BOOST_CI_INSTALL_TEST) 12 | find_package(boost_dynamic_bitset REQUIRED) 13 | else() 14 | set(BOOST_INCLUDE_LIBRARIES dynamic_bitset) 15 | add_subdirectory(../../../.. deps/boost EXCLUDE_FROM_ALL) 16 | endif() 17 | 18 | add_executable(main main.cpp) 19 | target_link_libraries(main Boost::dynamic_bitset) 20 | 21 | enable_testing() 22 | add_test(NAME main COMMAND main) 23 | -------------------------------------------------------------------------------- /test/cmake_test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | const boost::dynamic_bitset<> db{3, 4}; 6 | 7 | return db[2] ? 0 : 1; 8 | } 9 | -------------------------------------------------------------------------------- /test/dyn_bitset_unit_tests1.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006 Gennaro Prota 4 | // Copyright (c) 2014 Ahmed Charles 5 | // Copyright (c) 2014 Riccardo Marcangelo 6 | // 7 | // Copyright (c) 2014 Glen Joseph Fernandes 8 | // (glenjofe@gmail.com) 9 | // 10 | // Distributed under the Boost Software License, Version 1.0. 11 | // (See accompanying file LICENSE_1_0.txt or copy at 12 | // http://www.boost.org/LICENSE_1_0.txt) 13 | // 14 | // ----------------------------------------------------------- 15 | 16 | #include "bitset_test.hpp" 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #if !defined(BOOST_NO_CXX11_ALLOCATOR) 24 | #include 25 | 26 | template 27 | class minimal_allocator { 28 | public: 29 | typedef T value_type; 30 | 31 | minimal_allocator() {} 32 | 33 | template 34 | minimal_allocator(const minimal_allocator&) {} 35 | 36 | T* allocate(std::size_t n) { 37 | void* p = std::malloc(sizeof(T) * n); 38 | if (!p) { 39 | throw std::bad_alloc(); 40 | } 41 | return static_cast(p); 42 | } 43 | 44 | void deallocate(T* p, std::size_t) { 45 | std::free(p); 46 | } 47 | }; 48 | #endif 49 | 50 | #define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0])) 51 | 52 | 53 | // Codewarrior 8.3 for Win fails without this. 54 | // Thanks Howard Hinnant ;) 55 | #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x 56 | # pragma parse_func_templ off 57 | #endif 58 | 59 | 60 | template 61 | void run_string_tests(const String& s 62 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests) 63 | ) 64 | { 65 | 66 | const std::size_t len = s.length(); 67 | const std::size_t step = len/4 ? len/4 : 1; 68 | 69 | // bitset length determined by the string-related arguments 70 | std::size_t i; 71 | for (i = 0; i <= len/2 ; i += step) { 72 | Tests::from_string(s, i, len/2); // len/2 - i bits 73 | Tests::from_string(s, i, len); // len - i bits 74 | Tests::from_string(s, i, 1 + len*2); // len - i bits 75 | } 76 | 77 | // bitset length explicitly specified 78 | for (i = 0; i <= len/2; i += step) { 79 | for (std::size_t sz = 0; sz <= len*4; sz+= step*2) { 80 | Tests::from_string(s, i, len/2, sz); 81 | Tests::from_string(s, i, len, sz); 82 | Tests::from_string(s, i, 1 + len*2, sz); 83 | 84 | } 85 | } 86 | 87 | } 88 | 89 | // tests the do-the-right-thing constructor dispatch 90 | template 91 | void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests) 92 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) ) 93 | { 94 | 95 | const int bits_per_block = Tests::bits_per_block; 96 | const int width = std::numeric_limits::digits; 97 | const T ma = (std::numeric_limits::max)(); 98 | const T mi = (std::numeric_limits::min)(); 99 | 100 | int sizes[] = { 101 | 0, 7*width/10, width, 13*width/10, 3*width, 102 | 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block 103 | }; 104 | 105 | const T numbers[] = { 106 | T(-1), T(-3), T(-8), T(-15), T(mi/2), T(mi), 107 | T(0), T(1), T(3), T(8), T(15), T(ma/2), T(ma) 108 | }; 109 | 110 | for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) { 111 | for (std::size_t n = 0; n < BOOST_BITSET_TEST_COUNT(numbers); ++n ) { 112 | 113 | // can match ctor from ulong or templated one 114 | Tests::from_unsigned_long(sizes[s], numbers[n]); 115 | 116 | typedef std::size_t compare_type; 117 | const compare_type sz = sizes[s]; 118 | // this condition is to be sure that size is representable in T, so 119 | // that for signed T's we avoid implementation-defined behavior [if ma 120 | // is larger than what std::size_t can hold then this is ok for our 121 | // purposes: our sizes are anyhow < max(size_t)], which in turn could 122 | // make the first argument of from_unsigned_long() a small negative, 123 | // later converted to a very large unsigned. Example: signed 8-bit 124 | // char (CHAR_MAX=127), bits_per_block=64, sz = 192 > 127. 125 | const bool fits = 126 | sz <= static_cast(ma); 127 | 128 | if (fits) { 129 | // can match templated ctor only (so we test dispatching) 130 | Tests::from_unsigned_long(static_cast(sizes[s]), numbers[n]); 131 | } 132 | 133 | } 134 | } 135 | 136 | } 137 | 138 | 139 | template 140 | void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 141 | { 142 | typedef boost::dynamic_bitset bitset_type; 143 | typedef bitset_test Tests; 144 | const int bits_per_block = bitset_type::bits_per_block; 145 | 146 | const std::string long_string = get_long_string(); 147 | const Block all_1s = static_cast(-1); 148 | 149 | //===================================================================== 150 | // Test construction from unsigned long 151 | { 152 | // NOTE: 153 | // 154 | // 1. keep this in sync with the numeric types supported 155 | // for constructor dispatch (of course) 156 | // 2. bool is tested separately; ugly and inelegant, but 157 | // we don't have much time to think of a better solution 158 | // which is likely to work on broken compilers 159 | // 160 | const int sizes[] = { 161 | 0, 1, 3, 162 | 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block 163 | }; 164 | 165 | const bool values[] = { false, true }; 166 | 167 | for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) { 168 | for (std::size_t v = 0; v < BOOST_BITSET_TEST_COUNT(values); ++v) { 169 | Tests::from_unsigned_long(sizes[s], values[v]); 170 | Tests::from_unsigned_long(sizes[s] != 0, values[v]); 171 | } 172 | } 173 | 174 | run_numeric_ctor_tests(); 175 | 176 | #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) 177 | run_numeric_ctor_tests(); 178 | #endif 179 | 180 | run_numeric_ctor_tests(); 181 | run_numeric_ctor_tests(); 182 | run_numeric_ctor_tests(); 183 | run_numeric_ctor_tests(); 184 | 185 | run_numeric_ctor_tests(); 186 | run_numeric_ctor_tests(); 187 | run_numeric_ctor_tests(); 188 | run_numeric_ctor_tests(); 189 | 190 | #if defined(BOOST_HAS_LONG_LONG) 191 | run_numeric_ctor_tests(); 192 | run_numeric_ctor_tests(); 193 | #endif 194 | 195 | } 196 | //===================================================================== 197 | // Test construction from a string 198 | { 199 | 200 | run_string_tests(std::string("")); // empty string 201 | run_string_tests(std::string("1")); 202 | 203 | run_string_tests(long_string); 204 | 205 | # if !defined BOOST_NO_STD_WSTRING 206 | // I need to decide what to do for non "C" locales here. On 207 | // one hand I should have better tests. On the other one 208 | // I don't want tests for dynamic_bitset to cope with locales, 209 | // ctype::widen, etc. (but that's what you deserve when you 210 | // don't separate concerns at the library level) 211 | // 212 | run_string_tests( 213 | std::wstring(L"11111000000111111111010101010101010101010111111")); 214 | # endif 215 | 216 | // Note that these are _valid_ arguments 217 | Tests::from_string(std::string("x11y"), 1, 2); 218 | Tests::from_string(std::string("x11"), 1, 10); 219 | Tests::from_string(std::string("x11"), 1, 10, 10); 220 | 221 | } 222 | //===================================================================== 223 | // test from_block_range 224 | { 225 | std::vector blocks; 226 | Tests::from_block_range(blocks); 227 | } 228 | { 229 | std::vector blocks(3); 230 | blocks[0] = static_cast(0); 231 | blocks[1] = static_cast(1); 232 | blocks[2] = all_1s; 233 | Tests::from_block_range(blocks); 234 | } 235 | { 236 | const unsigned int n = (std::numeric_limits::max)(); 237 | std::vector blocks(n); 238 | for (typename std::vector::size_type i = 0; i < n; ++i) 239 | blocks[i] = static_cast(i); 240 | Tests::from_block_range(blocks); 241 | } 242 | //===================================================================== 243 | // test to_block_range 244 | { 245 | bitset_type b; 246 | Tests::to_block_range(b); 247 | } 248 | { 249 | bitset_type b(1, 1ul); 250 | Tests::to_block_range(b); 251 | } 252 | { 253 | bitset_type b(long_string); 254 | Tests::to_block_range(b); 255 | } 256 | 257 | //===================================================================== 258 | // Test copy constructor 259 | { 260 | boost::dynamic_bitset b; 261 | Tests::copy_constructor(b); 262 | } 263 | { 264 | boost::dynamic_bitset b(std::string("0")); 265 | Tests::copy_constructor(b); 266 | } 267 | { 268 | boost::dynamic_bitset b(long_string); 269 | Tests::copy_constructor(b); 270 | } 271 | //===================================================================== 272 | // Test copy assignment operator 273 | { 274 | bitset_type a, b; 275 | Tests::copy_assignment_operator(a, b); 276 | } 277 | { 278 | bitset_type a(std::string("1")), b(std::string("0")); 279 | Tests::copy_assignment_operator(a, b); 280 | } 281 | { 282 | bitset_type a(long_string), b(long_string); 283 | Tests::copy_assignment_operator(a, b); 284 | } 285 | { 286 | bitset_type a; 287 | bitset_type b(long_string); // b greater than a, a empty 288 | Tests::copy_assignment_operator(a, b); 289 | } 290 | { 291 | bitset_type a(std::string("0")); 292 | bitset_type b(long_string); // b greater than a 293 | Tests::copy_assignment_operator(a, b); 294 | } 295 | 296 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 297 | //===================================================================== 298 | // Test move constructor 299 | { 300 | boost::dynamic_bitset b; 301 | Tests::move_constructor(b); 302 | } 303 | { 304 | boost::dynamic_bitset b(std::string("0")); 305 | Tests::move_constructor(b); 306 | } 307 | { 308 | boost::dynamic_bitset b(long_string); 309 | Tests::move_constructor(b); 310 | } 311 | //===================================================================== 312 | // Test move assignment operator 313 | { 314 | bitset_type a, b; 315 | Tests::move_assignment_operator(a, b); 316 | } 317 | { 318 | bitset_type a(std::string("1")), b(std::string("0")); 319 | Tests::move_assignment_operator(a, b); 320 | } 321 | { 322 | bitset_type a(long_string), b(long_string); 323 | Tests::move_assignment_operator(a, b); 324 | } 325 | { 326 | bitset_type a; 327 | bitset_type b(long_string); // b greater than a, a empty 328 | Tests::move_assignment_operator(a, b); 329 | } 330 | { 331 | bitset_type a(std::string("0")); 332 | bitset_type b(long_string); // b greater than a 333 | Tests::move_assignment_operator(a, b); 334 | } 335 | #endif // BOOST_NO_CXX11_RVALUE_REFERENCES 336 | //===================================================================== 337 | // Test swap 338 | { 339 | bitset_type a; 340 | bitset_type b(std::string("1")); 341 | Tests::swap(a, b); 342 | Tests::swap(b, a); 343 | Tests::swap(a, a); 344 | } 345 | { 346 | bitset_type a; 347 | bitset_type b(long_string); 348 | Tests::swap(a, b); 349 | Tests::swap(b, a); 350 | } 351 | { 352 | bitset_type a(std::string("0")); 353 | bitset_type b(long_string); 354 | Tests::swap(a, b); 355 | Tests::swap(b, a); 356 | Tests::swap(a, a); 357 | Tests::swap(b, b); 358 | } 359 | //===================================================================== 360 | // Test resize 361 | { 362 | boost::dynamic_bitset a; 363 | Tests::resize(a); 364 | } 365 | { 366 | boost::dynamic_bitset a(std::string("0")); 367 | Tests::resize(a); 368 | } 369 | { 370 | boost::dynamic_bitset a(std::string("1")); 371 | Tests::resize(a); 372 | } 373 | { 374 | boost::dynamic_bitset a(long_string); 375 | Tests::resize(a); 376 | } 377 | //===================================================================== 378 | // Test clear 379 | { 380 | boost::dynamic_bitset a; 381 | Tests::clear(a); 382 | } 383 | { 384 | boost::dynamic_bitset a(long_string); 385 | Tests::clear(a); 386 | } 387 | //===================================================================== 388 | // Test pop back 389 | { 390 | boost::dynamic_bitset a(std::string("01")); 391 | Tests::pop_back(a); 392 | } 393 | { 394 | boost::dynamic_bitset a(std::string("10")); 395 | Tests::pop_back(a); 396 | } 397 | { 398 | const int size_to_fill_all_blocks = 4 * bits_per_block; 399 | boost::dynamic_bitset a(size_to_fill_all_blocks, 255ul); 400 | Tests::pop_back(a); 401 | } 402 | { 403 | boost::dynamic_bitset a(long_string); 404 | Tests::pop_back(a); 405 | } 406 | //===================================================================== 407 | // Test append bit 408 | { 409 | boost::dynamic_bitset a; 410 | Tests::append_bit(a); 411 | } 412 | { 413 | boost::dynamic_bitset a(std::string("0")); 414 | Tests::append_bit(a); 415 | } 416 | { 417 | boost::dynamic_bitset a(std::string("1")); 418 | Tests::append_bit(a); 419 | } 420 | { 421 | const int size_to_fill_all_blocks = 4 * bits_per_block; 422 | boost::dynamic_bitset a(size_to_fill_all_blocks, 255ul); 423 | Tests::append_bit(a); 424 | } 425 | { 426 | boost::dynamic_bitset a(long_string); 427 | Tests::append_bit(a); 428 | } 429 | //===================================================================== 430 | // Test append block 431 | { 432 | boost::dynamic_bitset a; 433 | Tests::append_block(a); 434 | } 435 | { 436 | boost::dynamic_bitset a(std::string("0")); 437 | Tests::append_block(a); 438 | } 439 | { 440 | boost::dynamic_bitset a(std::string("1")); 441 | Tests::append_block(a); 442 | } 443 | { 444 | const int size_to_fill_all_blocks = 4 * bits_per_block; 445 | boost::dynamic_bitset a(size_to_fill_all_blocks, 15ul); 446 | Tests::append_block(a); 447 | } 448 | { 449 | boost::dynamic_bitset a(long_string); 450 | Tests::append_block(a); 451 | } 452 | //===================================================================== 453 | // Test append block range 454 | { 455 | boost::dynamic_bitset a; 456 | std::vector blocks; 457 | Tests::append_block_range(a, blocks); 458 | } 459 | { 460 | boost::dynamic_bitset a(std::string("0")); 461 | std::vector blocks(3); 462 | blocks[0] = static_cast(0); 463 | blocks[1] = static_cast(1); 464 | blocks[2] = all_1s; 465 | Tests::append_block_range(a, blocks); 466 | } 467 | { 468 | boost::dynamic_bitset a(std::string("1")); 469 | const unsigned int n = (std::numeric_limits::max)(); 470 | std::vector blocks(n); 471 | for (typename std::vector::size_type i = 0; i < n; ++i) 472 | blocks[i] = static_cast(i); 473 | Tests::append_block_range(a, blocks); 474 | } 475 | { 476 | boost::dynamic_bitset a; 477 | a.append(Block(1)); 478 | a.append(Block(2)); 479 | Block x[] = {3, 4, 5}; 480 | std::size_t sz = sizeof(x) / sizeof(x[0]); 481 | std::vector blocks(x, x + sz); 482 | Tests::append_block_range(a, blocks); 483 | } 484 | { 485 | boost::dynamic_bitset a(long_string); 486 | std::vector blocks(3); 487 | blocks[0] = static_cast(0); 488 | blocks[1] = static_cast(1); 489 | blocks[2] = all_1s; 490 | Tests::append_block_range(a, blocks); 491 | } 492 | //===================================================================== 493 | // Test bracket operator 494 | { 495 | boost::dynamic_bitset b1; 496 | std::vector bitvec1; 497 | Tests::operator_bracket(b1, bitvec1); 498 | } 499 | { 500 | boost::dynamic_bitset b(std::string("1")); 501 | std::vector bit_vec(1, true); 502 | Tests::operator_bracket(b, bit_vec); 503 | } 504 | { 505 | boost::dynamic_bitset b(long_string); 506 | std::size_t n = long_string.size(); 507 | std::vector bit_vec(n); 508 | for (std::size_t i = 0; i < n; ++i) 509 | bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1; 510 | Tests::operator_bracket(b, bit_vec); 511 | } 512 | //===================================================================== 513 | // Test at 514 | { 515 | boost::dynamic_bitset b1; 516 | std::vector bitvec1; 517 | Tests::at(b1, bitvec1); 518 | } 519 | { 520 | boost::dynamic_bitset b(std::string("1")); 521 | std::vector bit_vec(1, true); 522 | Tests::at(b, bit_vec); 523 | } 524 | { 525 | boost::dynamic_bitset b(long_string); 526 | std::size_t n = long_string.size(); 527 | std::vector bit_vec(n); 528 | for (std::size_t i = 0; i < n; ++i) 529 | bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1; 530 | Tests::at(b, bit_vec); 531 | } 532 | #if !defined(BOOST_NO_CXX11_ALLOCATOR) 533 | { 534 | typedef boost::dynamic_bitset > Bitset; 536 | Bitset b; 537 | bitset_test::max_size(b); 538 | } 539 | #endif 540 | // Test copy-initialize with default constructor 541 | { 542 | boost::dynamic_bitset b[1] = {}; 543 | (void)b; 544 | } 545 | } 546 | 547 | int 548 | main() 549 | { 550 | run_test_cases(); 551 | run_test_cases(); 552 | run_test_cases(); 553 | run_test_cases(); 554 | # ifdef BOOST_HAS_LONG_LONG 555 | run_test_cases< ::boost::ulong_long_type>(); 556 | # endif 557 | 558 | return boost::report_errors(); 559 | } 560 | -------------------------------------------------------------------------------- /test/dyn_bitset_unit_tests2.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006 Gennaro Prota 4 | // Copyright (c) 2014 Ahmed Charles 5 | // Copyright (c) 2018 Evgeny Shulgin 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. 8 | // (See accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // ----------------------------------------------------------- 12 | 13 | #include "bitset_test.hpp" 14 | #include 15 | #include 16 | 17 | 18 | template 19 | void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 20 | { 21 | typedef boost::dynamic_bitset bitset_type; 22 | typedef bitset_test< bitset_type > Tests; 23 | const int bits_per_block = bitset_type::bits_per_block; 24 | 25 | std::string long_string = get_long_string(); 26 | 27 | //===================================================================== 28 | // Test operator&= 29 | { 30 | boost::dynamic_bitset lhs, rhs; 31 | Tests::and_assignment(lhs, rhs); 32 | } 33 | { 34 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 35 | Tests::and_assignment(lhs, rhs); 36 | } 37 | { 38 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 39 | Tests::and_assignment(lhs, rhs); 40 | } 41 | { 42 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 43 | Tests::and_assignment(lhs, rhs); 44 | } 45 | //===================================================================== 46 | // Test operator |= 47 | { 48 | boost::dynamic_bitset lhs, rhs; 49 | Tests::or_assignment(lhs, rhs); 50 | } 51 | { 52 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 53 | Tests::or_assignment(lhs, rhs); 54 | } 55 | { 56 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 57 | Tests::or_assignment(lhs, rhs); 58 | } 59 | { 60 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 61 | Tests::or_assignment(lhs, rhs); 62 | } 63 | //===================================================================== 64 | // Test operator^= 65 | { 66 | boost::dynamic_bitset lhs, rhs; 67 | Tests::xor_assignment(lhs, rhs); 68 | } 69 | { 70 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 71 | Tests::xor_assignment(lhs, rhs); 72 | } 73 | { 74 | boost::dynamic_bitset lhs(std::string("0")), rhs(std::string("1")); 75 | Tests::xor_assignment(lhs, rhs); 76 | } 77 | { 78 | boost::dynamic_bitset lhs(long_string), rhs(long_string); 79 | Tests::xor_assignment(lhs, rhs); 80 | } 81 | //===================================================================== 82 | // Test operator-= 83 | { 84 | boost::dynamic_bitset lhs, rhs; 85 | Tests::sub_assignment(lhs, rhs); 86 | } 87 | { 88 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 89 | Tests::sub_assignment(lhs, rhs); 90 | } 91 | { 92 | boost::dynamic_bitset lhs(std::string("0")), rhs(std::string("1")); 93 | Tests::sub_assignment(lhs, rhs); 94 | } 95 | { 96 | boost::dynamic_bitset lhs(long_string), rhs(long_string); 97 | Tests::sub_assignment(lhs, rhs); 98 | } 99 | //===================================================================== 100 | // Test operator<<= 101 | { // case pos == 0 102 | std::size_t pos = 0; 103 | { 104 | boost::dynamic_bitset b; 105 | Tests::shift_left_assignment(b, pos); 106 | } 107 | { 108 | boost::dynamic_bitset b(std::string("1010")); 109 | Tests::shift_left_assignment(b, pos); 110 | } 111 | { 112 | boost::dynamic_bitset b(long_string); 113 | Tests::shift_left_assignment(b, pos); 114 | } 115 | } 116 | { 117 | // test with both multiple and 118 | // non multiple of bits_per_block 119 | const int how_many = 10; 120 | for (int i = 1; i <= how_many; ++i) { 121 | std::size_t multiple = i * bits_per_block; 122 | std::size_t non_multiple = multiple - 1; 123 | boost::dynamic_bitset b(long_string); 124 | 125 | Tests::shift_left_assignment(b, multiple); 126 | Tests::shift_left_assignment(b, non_multiple); 127 | } 128 | } 129 | { // case pos == size()/2 130 | std::size_t pos = long_string.size() / 2; 131 | boost::dynamic_bitset b(long_string); 132 | Tests::shift_left_assignment(b, pos); 133 | } 134 | { // case pos >= n 135 | std::size_t pos = long_string.size(); 136 | boost::dynamic_bitset b(long_string); 137 | Tests::shift_left_assignment(b, pos); 138 | } 139 | //===================================================================== 140 | // Test operator>>= 141 | { // case pos == 0 142 | std::size_t pos = 0; 143 | { 144 | boost::dynamic_bitset b; 145 | Tests::shift_right_assignment(b, pos); 146 | } 147 | { 148 | boost::dynamic_bitset b(std::string("1010")); 149 | Tests::shift_right_assignment(b, pos); 150 | } 151 | { 152 | boost::dynamic_bitset b(long_string); 153 | Tests::shift_right_assignment(b, pos); 154 | } 155 | } 156 | { 157 | // test with both multiple and 158 | // non multiple of bits_per_block 159 | const int how_many = 10; 160 | for (int i = 1; i <= how_many; ++i) { 161 | std::size_t multiple = i * bits_per_block; 162 | std::size_t non_multiple = multiple - 1; 163 | boost::dynamic_bitset b(long_string); 164 | 165 | Tests::shift_right_assignment(b, multiple); 166 | Tests::shift_right_assignment(b, non_multiple); 167 | } 168 | 169 | } 170 | { // case pos == size()/2 171 | std::size_t pos = long_string.size() / 2; 172 | boost::dynamic_bitset b(long_string); 173 | Tests::shift_right_assignment(b, pos); 174 | } 175 | { // case pos >= n 176 | std::size_t pos = long_string.size(); 177 | boost::dynamic_bitset b(long_string); 178 | Tests::shift_right_assignment(b, pos); 179 | } 180 | //===================================================================== 181 | // test b.set() 182 | { 183 | boost::dynamic_bitset b; 184 | Tests::set_all(b); 185 | } 186 | { 187 | boost::dynamic_bitset b(std::string("0")); 188 | Tests::set_all(b); 189 | } 190 | { 191 | boost::dynamic_bitset b(long_string); 192 | Tests::set_all(b); 193 | } 194 | //===================================================================== 195 | // Test b.set(pos) 196 | { // case pos >= b.size() 197 | boost::dynamic_bitset b; 198 | Tests::set_one(b, 0, true); 199 | Tests::set_one(b, 0, false); 200 | } 201 | { // case pos < b.size() 202 | boost::dynamic_bitset b(std::string("0")); 203 | Tests::set_one(b, 0, true); 204 | Tests::set_one(b, 0, false); 205 | } 206 | { // case pos == b.size() / 2 207 | boost::dynamic_bitset b(long_string); 208 | Tests::set_one(b, long_string.size()/2, true); 209 | Tests::set_one(b, long_string.size()/2, false); 210 | } 211 | //===================================================================== 212 | // Test b.set(pos, len) 213 | { // case size is 1 214 | boost::dynamic_bitset b(std::string("0")); 215 | Tests::set_segment(b, 0, 1, true); 216 | Tests::set_segment(b, 0, 1, false); 217 | } 218 | { // case fill the whole set 219 | boost::dynamic_bitset b(long_string); 220 | Tests::set_segment(b, 0, b.size(), true); 221 | Tests::set_segment(b, 0, b.size(), false); 222 | } 223 | { // case pos = size / 4, len = size / 2 224 | boost::dynamic_bitset b(long_string); 225 | Tests::set_segment(b, b.size() / 4, b.size() / 2, true); 226 | Tests::set_segment(b, b.size() / 4, b.size() / 2, false); 227 | } 228 | { // case pos = block_size / 2, len = size - block_size 229 | boost::dynamic_bitset b(long_string); 230 | Tests::set_segment(b, boost::dynamic_bitset::bits_per_block / 2, 231 | b.size() - boost::dynamic_bitset::bits_per_block, true); 232 | Tests::set_segment(b, boost::dynamic_bitset::bits_per_block / 2, 233 | b.size() - boost::dynamic_bitset::bits_per_block, false); 234 | } 235 | { // case pos = 1, len = size - 2 236 | boost::dynamic_bitset b(long_string); 237 | Tests::set_segment(b, 1, b.size() - 2, true); 238 | Tests::set_segment(b, 1, b.size() - 2, false); 239 | } 240 | { // case pos = 3, len = 7 241 | boost::dynamic_bitset b(long_string); 242 | Tests::set_segment(b, 3, 7, true); 243 | Tests::set_segment(b, 3, 7, false); 244 | } 245 | //===================================================================== 246 | // Test b.reset() 247 | { 248 | boost::dynamic_bitset b; 249 | Tests::reset_all(b); 250 | } 251 | { 252 | boost::dynamic_bitset b(std::string("0")); 253 | Tests::reset_all(b); 254 | } 255 | { 256 | boost::dynamic_bitset b(long_string); 257 | Tests::reset_all(b); 258 | } 259 | //===================================================================== 260 | // Test b.reset(pos) 261 | { // case pos >= b.size() 262 | boost::dynamic_bitset b; 263 | Tests::reset_one(b, 0); 264 | } 265 | { // case pos < b.size() 266 | boost::dynamic_bitset b(std::string("0")); 267 | Tests::reset_one(b, 0); 268 | } 269 | { // case pos == b.size() / 2 270 | boost::dynamic_bitset b(long_string); 271 | Tests::reset_one(b, long_string.size()/2); 272 | } 273 | //===================================================================== 274 | // Test b.reset(pos, len) 275 | { // case size is 1 276 | boost::dynamic_bitset b(std::string("0")); 277 | Tests::reset_segment(b, 0, 1); 278 | } 279 | { // case fill the whole set 280 | boost::dynamic_bitset b(long_string); 281 | Tests::reset_segment(b, 0, b.size()); 282 | } 283 | { // case pos = size / 4, len = size / 2 284 | boost::dynamic_bitset b(long_string); 285 | Tests::reset_segment(b, b.size() / 4, b.size() / 2); 286 | } 287 | { // case pos = block_size / 2, len = size - block_size 288 | boost::dynamic_bitset b(long_string); 289 | Tests::reset_segment(b, boost::dynamic_bitset::bits_per_block / 2, 290 | b.size() - boost::dynamic_bitset::bits_per_block); 291 | } 292 | { // case pos = 1, len = size - 2 293 | boost::dynamic_bitset b(long_string); 294 | Tests::reset_segment(b, 1, b.size() - 2); 295 | } 296 | { // case pos = 3, len = 7 297 | boost::dynamic_bitset b(long_string); 298 | Tests::reset_segment(b, 3, 7); 299 | } 300 | //===================================================================== 301 | // Test ~b 302 | { 303 | boost::dynamic_bitset b; 304 | Tests::operator_flip(b); 305 | } 306 | { 307 | boost::dynamic_bitset b(std::string("1")); 308 | Tests::operator_flip(b); 309 | } 310 | { 311 | boost::dynamic_bitset b(long_string); 312 | Tests::operator_flip(b); 313 | } 314 | //===================================================================== 315 | // Test b.flip() 316 | { 317 | boost::dynamic_bitset b; 318 | Tests::flip_all(b); 319 | } 320 | { 321 | boost::dynamic_bitset b(std::string("1")); 322 | Tests::flip_all(b); 323 | } 324 | { 325 | boost::dynamic_bitset b(long_string); 326 | Tests::flip_all(b); 327 | } 328 | //===================================================================== 329 | // Test b.flip(pos) 330 | { // case pos >= b.size() 331 | boost::dynamic_bitset b; 332 | Tests::flip_one(b, 0); 333 | } 334 | { // case pos < b.size() 335 | boost::dynamic_bitset b(std::string("0")); 336 | Tests::flip_one(b, 0); 337 | } 338 | { // case pos == b.size() / 2 339 | boost::dynamic_bitset b(long_string); 340 | Tests::flip_one(b, long_string.size()/2); 341 | } 342 | //===================================================================== 343 | // Test b.flip(pos, len) 344 | { // case size is 1 345 | boost::dynamic_bitset b(std::string("0")); 346 | Tests::flip_segment(b, 0, 1); 347 | } 348 | { // case fill the whole set 349 | boost::dynamic_bitset b(long_string); 350 | Tests::flip_segment(b, 0, b.size()); 351 | } 352 | { // case pos = size / 4, len = size / 2 353 | boost::dynamic_bitset b(long_string); 354 | Tests::flip_segment(b, b.size() / 4, b.size() / 2); 355 | } 356 | { // case pos = block_size / 2, len = size - block_size 357 | boost::dynamic_bitset b(long_string); 358 | Tests::flip_segment(b, boost::dynamic_bitset::bits_per_block / 2, 359 | b.size() - boost::dynamic_bitset::bits_per_block); 360 | } 361 | { // case pos = 1, len = size - 2 362 | boost::dynamic_bitset b(long_string); 363 | Tests::flip_segment(b, 1, b.size() - 2); 364 | } 365 | { // case pos = 3, len = 7 366 | boost::dynamic_bitset b(long_string); 367 | Tests::flip_segment(b, 3, 7); 368 | } 369 | } 370 | 371 | int 372 | main() 373 | { 374 | run_test_cases(); 375 | run_test_cases(); 376 | run_test_cases(); 377 | run_test_cases(); 378 | # ifdef BOOST_HAS_LONG_LONG 379 | run_test_cases< ::boost::ulong_long_type>(); 380 | # endif 381 | 382 | return boost::report_errors(); 383 | } 384 | -------------------------------------------------------------------------------- /test/dyn_bitset_unit_tests3.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006 Gennaro Prota 4 | // Copyright (c) 2014 Ahmed Charles 5 | // Copyright (c) 2014 Riccardo Marcangelo 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. 8 | // (See accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // ----------------------------------------------------------- 12 | 13 | #include 14 | #include "bitset_test.hpp" 15 | #include 16 | #include 17 | #include 18 | 19 | template 20 | void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 21 | { 22 | // a bunch of typedefs which will be handy later on 23 | typedef boost::dynamic_bitset bitset_type; 24 | typedef bitset_test Tests; 25 | // typedef typename bitset_type::size_type size_type; // unusable with Borland 5.5.1 26 | 27 | std::string long_string = get_long_string(); 28 | std::size_t ul_width = std::numeric_limits::digits; 29 | 30 | //===================================================================== 31 | // Test b.empty() 32 | { 33 | bitset_type b; 34 | Tests::empty(b); 35 | } 36 | { 37 | bitset_type b(1, 1ul); 38 | Tests::empty(b); 39 | } 40 | { 41 | bitset_type b(bitset_type::bits_per_block 42 | + bitset_type::bits_per_block/2, 15ul); 43 | Tests::empty(b); 44 | } 45 | //===================================================================== 46 | // Test b.to_long() 47 | { 48 | boost::dynamic_bitset b; 49 | Tests::to_ulong(b); 50 | } 51 | { 52 | boost::dynamic_bitset b(std::string("1")); 53 | Tests::to_ulong(b); 54 | } 55 | { 56 | boost::dynamic_bitset b(bitset_type::bits_per_block, 57 | static_cast(-1)); 58 | Tests::to_ulong(b); 59 | } 60 | { 61 | std::string str(ul_width - 1, '1'); 62 | boost::dynamic_bitset b(str); 63 | Tests::to_ulong(b); 64 | } 65 | { 66 | std::string ul_str(ul_width, '1'); 67 | boost::dynamic_bitset b(ul_str); 68 | Tests::to_ulong(b); 69 | } 70 | { // case overflow 71 | boost::dynamic_bitset b(long_string); 72 | Tests::to_ulong(b); 73 | } 74 | //===================================================================== 75 | // Test to_string(b, str) 76 | { 77 | boost::dynamic_bitset b; 78 | Tests::to_string(b); 79 | } 80 | { 81 | boost::dynamic_bitset b(std::string("0")); 82 | Tests::to_string(b); 83 | } 84 | { 85 | boost::dynamic_bitset b(long_string); 86 | Tests::to_string(b); 87 | } 88 | //===================================================================== 89 | // Test b.count() 90 | { 91 | boost::dynamic_bitset b; 92 | Tests::count(b); 93 | } 94 | { 95 | boost::dynamic_bitset b(std::string("0")); 96 | Tests::count(b); 97 | } 98 | { 99 | boost::dynamic_bitset b(std::string("1")); 100 | Tests::count(b); 101 | } 102 | { 103 | boost::dynamic_bitset b(8, 255ul); 104 | Tests::count(b); 105 | } 106 | { 107 | boost::dynamic_bitset b(long_string); 108 | Tests::count(b); 109 | } 110 | //===================================================================== 111 | // Test b.size() 112 | { 113 | boost::dynamic_bitset b; 114 | Tests::size(b); 115 | } 116 | { 117 | boost::dynamic_bitset b(std::string("0")); 118 | Tests::size(b); 119 | } 120 | { 121 | boost::dynamic_bitset b(long_string); 122 | Tests::size(b); 123 | } 124 | //===================================================================== 125 | // Test b.capacity() 126 | { 127 | boost::dynamic_bitset b; 128 | Tests::capacity_test_one(b); 129 | } 130 | { 131 | boost::dynamic_bitset b(100); 132 | Tests::capacity_test_two(b); 133 | } 134 | //===================================================================== 135 | // Test b.reserve() 136 | { 137 | boost::dynamic_bitset b; 138 | Tests::reserve_test_one(b); 139 | } 140 | { 141 | boost::dynamic_bitset b(100); 142 | Tests::reserve_test_two(b); 143 | } 144 | //===================================================================== 145 | // Test b.shrink_to_fit() 146 | { 147 | boost::dynamic_bitset b; 148 | Tests::shrink_to_fit_test_one(b); 149 | } 150 | { 151 | boost::dynamic_bitset b(100); 152 | Tests::shrink_to_fit_test_two(b); 153 | } 154 | //===================================================================== 155 | // Test b.all() 156 | { 157 | boost::dynamic_bitset b; 158 | Tests::all(b); 159 | Tests::all(~b); 160 | Tests::all(b.set()); 161 | Tests::all(b.reset()); 162 | } 163 | { 164 | boost::dynamic_bitset b(std::string("0")); 165 | Tests::all(b); 166 | Tests::all(~b); 167 | Tests::all(b.set()); 168 | Tests::all(b.reset()); 169 | } 170 | { 171 | boost::dynamic_bitset b(long_string); 172 | Tests::all(b); 173 | Tests::all(~b); 174 | Tests::all(b.set()); 175 | Tests::all(b.reset()); 176 | } 177 | //===================================================================== 178 | // Test b.any() 179 | { 180 | boost::dynamic_bitset b; 181 | Tests::any(b); 182 | Tests::any(~b); 183 | Tests::any(b.set()); 184 | Tests::any(b.reset()); 185 | } 186 | { 187 | boost::dynamic_bitset b(std::string("0")); 188 | Tests::any(b); 189 | Tests::any(~b); 190 | Tests::any(b.set()); 191 | Tests::any(b.reset()); 192 | } 193 | { 194 | boost::dynamic_bitset b(long_string); 195 | Tests::any(b); 196 | Tests::any(~b); 197 | Tests::any(b.set()); 198 | Tests::any(b.reset()); 199 | } 200 | //===================================================================== 201 | // Test b.none() 202 | { 203 | boost::dynamic_bitset b; 204 | Tests::none(b); 205 | Tests::none(~b); 206 | Tests::none(b.set()); 207 | Tests::none(b.reset()); 208 | } 209 | { 210 | boost::dynamic_bitset b(std::string("0")); 211 | Tests::none(b); 212 | Tests::none(~b); 213 | Tests::none(b.set()); 214 | Tests::none(b.reset()); 215 | } 216 | { 217 | boost::dynamic_bitset b(long_string); 218 | Tests::none(b); 219 | Tests::none(~b); 220 | Tests::none(b.set()); 221 | Tests::none(b.reset()); 222 | } 223 | //===================================================================== 224 | // Test a.is_subset_of(b) 225 | { 226 | boost::dynamic_bitset a, b; 227 | Tests::subset(a, b); 228 | } 229 | { 230 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 231 | Tests::subset(a, b); 232 | } 233 | { 234 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 235 | Tests::subset(a, b); 236 | } 237 | { 238 | boost::dynamic_bitset a(long_string), b(long_string); 239 | Tests::subset(a, b); 240 | } 241 | { 242 | boost::dynamic_bitset a(long_string), b(long_string); 243 | a[long_string.size()/2].flip(); 244 | Tests::subset(a, b); 245 | } 246 | { 247 | boost::dynamic_bitset a(long_string), b(long_string); 248 | b[long_string.size()/2].flip(); 249 | Tests::subset(a, b); 250 | } 251 | //===================================================================== 252 | // Test a.is_proper_subset_of(b) 253 | { 254 | boost::dynamic_bitset a, b; 255 | Tests::proper_subset(a, b); 256 | } 257 | { 258 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 259 | Tests::proper_subset(a, b); 260 | } 261 | { 262 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 263 | Tests::proper_subset(a, b); 264 | } 265 | { 266 | boost::dynamic_bitset a(long_string), b(long_string); 267 | Tests::proper_subset(a, b); 268 | } 269 | { 270 | boost::dynamic_bitset a(long_string), b(long_string); 271 | a[long_string.size()/2].flip(); 272 | Tests::proper_subset(a, b); 273 | } 274 | { 275 | boost::dynamic_bitset a(long_string), b(long_string); 276 | b[long_string.size()/2].flip(); 277 | Tests::proper_subset(a, b); 278 | } 279 | //===================================================================== 280 | // Test intersects 281 | { 282 | bitset_type a; // empty 283 | bitset_type b; 284 | Tests::intersects(a, b); 285 | } 286 | { 287 | bitset_type a; 288 | bitset_type b(5, 8ul); 289 | Tests::intersects(a, b); 290 | } 291 | { 292 | bitset_type a(8, 0ul); 293 | bitset_type b(15, 0ul); 294 | b[9] = 1; 295 | Tests::intersects(a, b); 296 | } 297 | { 298 | bitset_type a(15, 0ul); 299 | bitset_type b(22, 0ul); 300 | a[14] = b[14] = 1; 301 | Tests::intersects(a, b); 302 | } 303 | //===================================================================== 304 | // Test find_first 305 | { 306 | // empty bitset 307 | bitset_type b; 308 | Tests::find_first(b); 309 | } 310 | { 311 | // bitset of size 1 312 | bitset_type b(1, 1ul); 313 | Tests::find_first(b); 314 | } 315 | { 316 | // all-0s bitset 317 | bitset_type b(4 * bitset_type::bits_per_block, 0ul); 318 | Tests::find_first(b); 319 | } 320 | { 321 | // first bit on 322 | bitset_type b(1, 1ul); 323 | Tests::find_first(b); 324 | } 325 | { 326 | // last bit on 327 | bitset_type b(4 * bitset_type::bits_per_block - 1, 0ul); 328 | b.set(b.size() - 1); 329 | Tests::find_first(b); 330 | } 331 | //===================================================================== 332 | // Test find_next and offset find_first 333 | { 334 | // empty bitset 335 | bitset_type b; 336 | 337 | // check 338 | Tests::find_pos(b, 0); 339 | Tests::find_pos(b, 1); 340 | Tests::find_pos(b, 200); 341 | Tests::find_pos(b, b.npos); 342 | } 343 | { 344 | // bitset of size 1 (find_next can never find) 345 | bitset_type b(1, 1ul); 346 | 347 | // check 348 | Tests::find_pos(b, 0); 349 | Tests::find_pos(b, 1); 350 | Tests::find_pos(b, 200); 351 | Tests::find_pos(b, b.npos); 352 | } 353 | { 354 | // all-1s bitset 355 | bitset_type b(16 * bitset_type::bits_per_block); 356 | b.set(); 357 | 358 | // check 359 | const typename bitset_type::size_type larger_than_size = 5 + b.size(); 360 | for(typename bitset_type::size_type i = 0; i <= larger_than_size; ++i) { 361 | Tests::find_pos(b, i); 362 | } 363 | Tests::find_pos(b, b.npos); 364 | } 365 | { 366 | // a bitset with 1s at block boundary only 367 | const int num_blocks = 32; 368 | const int block_width = bitset_type::bits_per_block; 369 | 370 | bitset_type b(num_blocks * block_width); 371 | typename bitset_type::size_type i = block_width - 1; 372 | for ( ; i < b.size(); i += block_width) { 373 | 374 | b.set(i); 375 | typename bitset_type::size_type first_in_block = i - (block_width - 1); 376 | b.set(first_in_block); 377 | } 378 | 379 | // check 380 | const typename bitset_type::size_type larger_than_size = 5 + b.size(); 381 | for (i = 0; i <= larger_than_size; ++i) { 382 | Tests::find_pos(b, i); 383 | } 384 | Tests::find_pos(b, b.npos); 385 | 386 | } 387 | { 388 | // bitset with alternate 1s and 0s 389 | const typename bitset_type::size_type sz = 1000; 390 | bitset_type b(sz); 391 | 392 | typename bitset_type::size_type i = 0; 393 | for ( ; i < sz; ++i) { 394 | b[i] = (i%2 == 0); 395 | } 396 | 397 | // check 398 | const typename bitset_type::size_type larger_than_size = 5 + b.size(); 399 | for (i = 0; i <= larger_than_size; ++i) { 400 | Tests::find_pos(b, i); 401 | } 402 | Tests::find_pos(b, b.npos); 403 | 404 | } 405 | //===================================================================== 406 | // Test operator== 407 | { 408 | boost::dynamic_bitset a, b; 409 | Tests::operator_equal(a, b); 410 | } 411 | { 412 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 413 | Tests::operator_equal(a, b); 414 | } 415 | { 416 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 417 | Tests::operator_equal(a, b); 418 | } 419 | { 420 | boost::dynamic_bitset a(long_string), b(long_string); 421 | Tests::operator_equal(a, b); 422 | } 423 | { 424 | boost::dynamic_bitset a(long_string), b(long_string); 425 | a[long_string.size()/2].flip(); 426 | Tests::operator_equal(a, b); 427 | } 428 | { 429 | boost::dynamic_bitset a(long_string), b(long_string); 430 | b[long_string.size()/2].flip(); 431 | Tests::operator_equal(a, b); 432 | } 433 | //===================================================================== 434 | // Test operator!= 435 | { 436 | boost::dynamic_bitset a, b; 437 | Tests::operator_not_equal(a, b); 438 | } 439 | { 440 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 441 | Tests::operator_not_equal(a, b); 442 | } 443 | { 444 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 445 | Tests::operator_not_equal(a, b); 446 | } 447 | { 448 | boost::dynamic_bitset a(long_string), b(long_string); 449 | Tests::operator_not_equal(a, b); 450 | } 451 | { 452 | boost::dynamic_bitset a(long_string), b(long_string); 453 | a[long_string.size()/2].flip(); 454 | Tests::operator_not_equal(a, b); 455 | } 456 | { 457 | boost::dynamic_bitset a(long_string), b(long_string); 458 | b[long_string.size()/2].flip(); 459 | Tests::operator_not_equal(a, b); 460 | } 461 | //===================================================================== 462 | // Test operator< 463 | { 464 | boost::dynamic_bitset a, b; 465 | Tests::operator_less_than(a, b); 466 | } 467 | { 468 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 469 | Tests::operator_less_than(a, b); 470 | } 471 | { 472 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 473 | Tests::operator_less_than(a, b); 474 | } 475 | { 476 | boost::dynamic_bitset a(std::string("10")), b(std::string("11")); 477 | Tests::operator_less_than(a, b); 478 | } 479 | { 480 | boost::dynamic_bitset a(std::string("101")), b(std::string("11")); 481 | Tests::operator_less_than(a, b); 482 | } 483 | { 484 | boost::dynamic_bitset a(std::string("10")), b(std::string("111")); 485 | Tests::operator_less_than(a, b); 486 | } 487 | { 488 | boost::dynamic_bitset a(long_string), b(long_string); 489 | Tests::operator_less_than(a, b); 490 | } 491 | { 492 | boost::dynamic_bitset a(long_string), b(long_string); 493 | a[long_string.size()/2].flip(); 494 | Tests::operator_less_than(a, b); 495 | } 496 | { 497 | boost::dynamic_bitset a(long_string), b(long_string); 498 | b[long_string.size()/2].flip(); 499 | Tests::operator_less_than(a, b); 500 | } 501 | // check for consistency with ulong behaviour when the sizes are equal 502 | { 503 | boost::dynamic_bitset a(3, 4ul), b(3, 5ul); 504 | assert(a < b); 505 | } 506 | { 507 | boost::dynamic_bitset a(3, 4ul), b(3, 4ul); 508 | assert(!(a < b)); 509 | } 510 | { 511 | boost::dynamic_bitset a(3, 5ul), b(3, 4ul); 512 | assert(!(a < b)); 513 | } 514 | // when the sizes are not equal lexicographic compare does not necessarily correspond to ulong behavior 515 | { 516 | boost::dynamic_bitset a(4, 4ul), b(3, 5ul); 517 | assert(a < b); 518 | } 519 | { 520 | boost::dynamic_bitset a(3, 4ul), b(4, 5ul); 521 | assert(!(a < b)); 522 | } 523 | { 524 | boost::dynamic_bitset a(4, 4ul), b(3, 4ul); 525 | assert(a < b); 526 | } 527 | { 528 | boost::dynamic_bitset a(3, 4ul), b(4, 4ul); 529 | assert(!(a < b)); 530 | } 531 | { 532 | boost::dynamic_bitset a(4, 5ul), b(3, 4ul); 533 | assert(a < b); 534 | } 535 | { 536 | boost::dynamic_bitset a(3, 5ul), b(4, 4ul); 537 | assert(!(a < b)); 538 | } 539 | //===================================================================== 540 | // Test operator<= 541 | { 542 | boost::dynamic_bitset a, b; 543 | Tests::operator_less_than_eq(a, b); 544 | } 545 | { 546 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 547 | Tests::operator_less_than_eq(a, b); 548 | } 549 | { 550 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 551 | Tests::operator_less_than_eq(a, b); 552 | } 553 | { 554 | boost::dynamic_bitset a(long_string), b(long_string); 555 | Tests::operator_less_than_eq(a, b); 556 | } 557 | { 558 | boost::dynamic_bitset a(long_string), b(long_string); 559 | a[long_string.size()/2].flip(); 560 | Tests::operator_less_than_eq(a, b); 561 | } 562 | { 563 | boost::dynamic_bitset a(long_string), b(long_string); 564 | b[long_string.size()/2].flip(); 565 | Tests::operator_less_than_eq(a, b); 566 | } 567 | // check for consistency with ulong behaviour 568 | { 569 | boost::dynamic_bitset a(3, 4ul), b(3, 5ul); 570 | assert(a <= b); 571 | } 572 | { 573 | boost::dynamic_bitset a(3, 4ul), b(3, 4ul); 574 | assert(a <= b); 575 | } 576 | { 577 | boost::dynamic_bitset a(3, 5ul), b(3, 4ul); 578 | assert(!(a <= b)); 579 | } 580 | //===================================================================== 581 | // Test operator> 582 | { 583 | boost::dynamic_bitset a, b; 584 | Tests::operator_greater_than(a, b); 585 | } 586 | { 587 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 588 | Tests::operator_greater_than(a, b); 589 | } 590 | { 591 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 592 | Tests::operator_greater_than(a, b); 593 | } 594 | { 595 | boost::dynamic_bitset a(long_string), b(long_string); 596 | Tests::operator_greater_than(a, b); 597 | } 598 | { 599 | boost::dynamic_bitset a(long_string), b(long_string); 600 | a[long_string.size()/2].flip(); 601 | Tests::operator_greater_than(a, b); 602 | } 603 | { 604 | boost::dynamic_bitset a(long_string), b(long_string); 605 | b[long_string.size()/2].flip(); 606 | Tests::operator_greater_than(a, b); 607 | } 608 | // check for consistency with ulong behaviour 609 | { 610 | boost::dynamic_bitset a(3, 4ul), b(3, 5ul); 611 | assert(!(a > b)); 612 | } 613 | { 614 | boost::dynamic_bitset a(3, 4ul), b(3, 4ul); 615 | assert(!(a > b)); 616 | } 617 | { 618 | boost::dynamic_bitset a(3, 5ul), b(3, 4ul); 619 | assert(a > b); 620 | } 621 | //===================================================================== 622 | // Test operator<= 623 | { 624 | boost::dynamic_bitset a, b; 625 | Tests::operator_greater_than_eq(a, b); 626 | } 627 | { 628 | boost::dynamic_bitset a(std::string("0")), b(std::string("0")); 629 | Tests::operator_greater_than_eq(a, b); 630 | } 631 | { 632 | boost::dynamic_bitset a(std::string("1")), b(std::string("1")); 633 | Tests::operator_greater_than_eq(a, b); 634 | } 635 | { 636 | boost::dynamic_bitset a(long_string), b(long_string); 637 | Tests::operator_greater_than_eq(a, b); 638 | } 639 | { 640 | boost::dynamic_bitset a(long_string), b(long_string); 641 | a[long_string.size()/2].flip(); 642 | Tests::operator_greater_than_eq(a, b); 643 | } 644 | { 645 | boost::dynamic_bitset a(long_string), b(long_string); 646 | b[long_string.size()/2].flip(); 647 | Tests::operator_greater_than_eq(a, b); 648 | } 649 | // check for consistency with ulong behaviour 650 | { 651 | boost::dynamic_bitset a(3, 4ul), b(3, 5ul); 652 | assert(!(a >= b)); 653 | } 654 | { 655 | boost::dynamic_bitset a(3, 4ul), b(3, 4ul); 656 | assert(a >= b); 657 | } 658 | { 659 | boost::dynamic_bitset a(3, 5ul), b(3, 4ul); 660 | assert(a >= b); 661 | } 662 | //===================================================================== 663 | // Test b.test(pos) 664 | { // case pos >= b.size() 665 | boost::dynamic_bitset b; 666 | Tests::test_bit(b, 0); 667 | } 668 | { // case pos < b.size() 669 | boost::dynamic_bitset b(std::string("0")); 670 | Tests::test_bit(b, 0); 671 | } 672 | { // case pos == b.size() / 2 673 | boost::dynamic_bitset b(long_string); 674 | Tests::test_bit(b, long_string.size()/2); 675 | } 676 | //===================================================================== 677 | // Test b.test_set(pos) 678 | { // case pos >= b.size() 679 | boost::dynamic_bitset b; 680 | Tests::test_set_bit(b, 0, true); 681 | Tests::test_set_bit(b, 0, false); 682 | } 683 | { // case pos < b.size() 684 | boost::dynamic_bitset b(std::string("0")); 685 | Tests::test_set_bit(b, 0, true); 686 | Tests::test_set_bit(b, 0, false); 687 | } 688 | { // case pos == b.size() / 2 689 | boost::dynamic_bitset b(long_string); 690 | Tests::test_set_bit(b, long_string.size() / 2, true); 691 | Tests::test_set_bit(b, long_string.size() / 2, false); 692 | } 693 | //===================================================================== 694 | // Test b << pos 695 | { // case pos == 0 696 | std::size_t pos = 0; 697 | boost::dynamic_bitset b(std::string("1010")); 698 | Tests::operator_shift_left(b, pos); 699 | } 700 | { // case pos == size()/2 701 | std::size_t pos = long_string.size() / 2; 702 | boost::dynamic_bitset b(long_string); 703 | Tests::operator_shift_left(b, pos); 704 | } 705 | { // case pos >= n 706 | std::size_t pos = long_string.size(); 707 | boost::dynamic_bitset b(long_string); 708 | Tests::operator_shift_left(b, pos); 709 | } 710 | //===================================================================== 711 | // Test b >> pos 712 | { // case pos == 0 713 | std::size_t pos = 0; 714 | boost::dynamic_bitset b(std::string("1010")); 715 | Tests::operator_shift_right(b, pos); 716 | } 717 | { // case pos == size()/2 718 | std::size_t pos = long_string.size() / 2; 719 | boost::dynamic_bitset b(long_string); 720 | Tests::operator_shift_right(b, pos); 721 | } 722 | { // case pos >= n 723 | std::size_t pos = long_string.size(); 724 | boost::dynamic_bitset b(long_string); 725 | Tests::operator_shift_right(b, pos); 726 | } 727 | //===================================================================== 728 | // Test a & b 729 | { 730 | boost::dynamic_bitset lhs, rhs; 731 | Tests::operator_and(lhs, rhs); 732 | } 733 | { 734 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 735 | Tests::operator_and(lhs, rhs); 736 | } 737 | { 738 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 739 | Tests::operator_and(lhs, rhs); 740 | } 741 | { 742 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 743 | Tests::operator_and(lhs, rhs); 744 | } 745 | //===================================================================== 746 | // Test a | b 747 | { 748 | boost::dynamic_bitset lhs, rhs; 749 | Tests::operator_or(lhs, rhs); 750 | } 751 | { 752 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 753 | Tests::operator_or(lhs, rhs); 754 | } 755 | { 756 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 757 | Tests::operator_or(lhs, rhs); 758 | } 759 | { 760 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 761 | Tests::operator_or(lhs, rhs); 762 | } 763 | //===================================================================== 764 | // Test a^b 765 | { 766 | boost::dynamic_bitset lhs, rhs; 767 | Tests::operator_xor(lhs, rhs); 768 | } 769 | { 770 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 771 | Tests::operator_xor(lhs, rhs); 772 | } 773 | { 774 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 775 | Tests::operator_xor(lhs, rhs); 776 | } 777 | { 778 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 779 | Tests::operator_xor(lhs, rhs); 780 | } 781 | //===================================================================== 782 | // Test a-b 783 | { 784 | boost::dynamic_bitset lhs, rhs; 785 | Tests::operator_sub(lhs, rhs); 786 | } 787 | { 788 | boost::dynamic_bitset lhs(std::string("1")), rhs(std::string("0")); 789 | Tests::operator_sub(lhs, rhs); 790 | } 791 | { 792 | boost::dynamic_bitset lhs(long_string.size(), 0), rhs(long_string); 793 | Tests::operator_sub(lhs, rhs); 794 | } 795 | { 796 | boost::dynamic_bitset lhs(long_string.size(), 1), rhs(long_string); 797 | Tests::operator_sub(lhs, rhs); 798 | } 799 | } 800 | 801 | 802 | int 803 | main() 804 | { 805 | run_test_cases(); 806 | run_test_cases(); 807 | run_test_cases(); 808 | run_test_cases(); 809 | # ifdef BOOST_HAS_LONG_LONG 810 | run_test_cases< ::boost::ulong_long_type>(); 811 | # endif 812 | 813 | return boost::report_errors(); 814 | } 815 | -------------------------------------------------------------------------------- /test/dyn_bitset_unit_tests4.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006 Gennaro Prota 4 | // 5 | // Distributed under the Boost Software License, Version 1.0. 6 | // (See accompanying file LICENSE_1_0.txt or copy at 7 | // http://www.boost.org/LICENSE_1_0.txt) 8 | // 9 | // ----------------------------------------------------------- 10 | 11 | #include 12 | #include 13 | #include // for std::size_t 14 | #include // for std::logic_error 15 | #include 16 | 17 | #include 18 | #if !defined (BOOST_NO_STRINGSTREAM) 19 | # include 20 | #endif 21 | 22 | #include "bitset_test.hpp" 23 | #include 24 | #include 25 | 26 | 27 | // Codewarrior 8.3 for Win fails without this. 28 | // Thanks Howard Hinnant ;) 29 | #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x 30 | # pragma parse_func_templ off 31 | #endif 32 | 33 | 34 | #if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE 35 | # define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS 36 | #endif 37 | 38 | #if !defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS 39 | std::wstring widen_string( const std::string & str, 40 | const std::locale & loc = std::locale() ) 41 | { 42 | std::wstring result; 43 | const std::string::size_type len = str.length(); 44 | if(len != 0) { 45 | 46 | typedef std::ctype ct_type; 47 | typedef std::wstring::traits_type tr_type; 48 | const ct_type & ct = BOOST_USE_FACET(ct_type, loc); 49 | 50 | result.resize(len); 51 | for (std::size_t i = 0; i < len; ++i) 52 | tr_type::assign(result[i], ct.widen(str[i])); 53 | 54 | } 55 | return result; 56 | } 57 | #endif 58 | 59 | template 60 | void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 61 | { 62 | 63 | typedef boost::dynamic_bitset bitset_type; 64 | typedef bitset_test Tests; 65 | 66 | //===================================================================== 67 | // Test stream operator<< 68 | { 69 | 70 | // The test "variables" are: the stream type and its state, the 71 | // exception mask, the width, the fill char and the padding side (left/right) 72 | 73 | std::ios::iostate masks[] = { 74 | std::ios::goodbit, 75 | std::ios::eofbit, 76 | std::ios::failbit, 77 | std::ios::eofbit | std::ios::failbit 78 | }; 79 | 80 | static std::string strings[] = { 81 | std::string(""), 82 | std::string("0"), 83 | std::string("1"), 84 | std::string("11100"), 85 | get_long_string() 86 | }; 87 | 88 | char fill_chars[] = { '*', 'x', ' ' }; 89 | 90 | std::size_t num_masks = sizeof(masks) / sizeof(masks[0]); 91 | std::size_t num_strings = sizeof(strings) / sizeof(strings[0]); 92 | std::size_t num_chars = sizeof(fill_chars) / sizeof(fill_chars[0]); 93 | 94 | std::fstream not_good_stream("dynamic_bitset_tests - this file shouldn't exist", 95 | std::ios::in); 96 | 97 | 98 | for (std::size_t mi = 0; mi < num_masks; ++mi) { 99 | for (std::size_t si = 0; si < num_strings; ++si) { 100 | 101 | std::streamsize slen = (std::streamsize)(strings[si].length()); 102 | 103 | assert( (std::numeric_limits::max)() 104 | >=(std::streamsize)(1+slen*2) ); 105 | 106 | for (std::size_t ci = 0; ci < num_chars; ++ci) { 107 | 108 | // note how "negative widths" are tested too 109 | const std::streamsize widths[] = { -1 - slen/2, 0, slen/2, 1 + slen*2 }; 110 | std::size_t num_widths = sizeof(widths) / sizeof(widths[0]); 111 | 112 | for (std::size_t wi = 0; wi < num_widths; ++wi) { 113 | std::streamsize w = widths[wi]; 114 | { 115 | // test 0 - stream !good() 116 | if(not_good_stream.good()) 117 | throw std::logic_error("Error in operator << tests" 118 | " - please, double check"); 119 | bitset_type b(strings[si]); 120 | not_good_stream.width(w); 121 | not_good_stream.fill(fill_chars[ci]); 122 | try { not_good_stream.exceptions(masks[mi]); } catch(...) {} 123 | 124 | Tests::stream_inserter(b, not_good_stream, ""); 125 | } 126 | { 127 | // test 1a - file stream 128 | scoped_temp_file stf; 129 | bitset_type b(strings[si]); 130 | std::ofstream file(stf.path().string().c_str(), std::ios::trunc); 131 | file.width(w); 132 | file.fill(fill_chars[ci]); 133 | file.exceptions(masks[mi]); 134 | Tests::stream_inserter(b, file, stf.path().string().c_str()); 135 | } 136 | { 137 | //NOTE: there are NO string stream tests 138 | } 139 | #if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS) 140 | { 141 | // test 1b - wide file stream 142 | scoped_temp_file stf; 143 | bitset_type b(strings[si]); 144 | std::wofstream file(stf.path().string().c_str()); 145 | file.width(w); 146 | file.fill(fill_chars[ci]); 147 | file.exceptions(masks[mi]); 148 | Tests::stream_inserter(b, file, stf.path().string().c_str()); 149 | } 150 | #endif 151 | } 152 | } 153 | } 154 | } // for (; mi..) 155 | 156 | } 157 | 158 | //===================================================================== 159 | // Test stream operator>> 160 | { 161 | 162 | // The test "variables" are: the stream type, the exception mask, 163 | // the actual contents (and/or state) of the stream, and width. 164 | // 165 | // With few exceptions, each test case consists of writing a different 166 | // assortment of digits and "whitespaces" to a text stream and then checking 167 | // that what was written gets read back unchanged. That's NOT guaranteed by 168 | // the standard, unless the assortment always ends with a '\n' and satisfies 169 | // other conditions (see C99, 7.19.2/2), however it works in practice and is 170 | // a good "real life" test. Some characters, such as '\v' and '\f', are not 171 | // used exactly because they are the ones which will most likely give problems 172 | // on some systems (for instance '\f' could actually be written as a sequence 173 | // of new-lines, and we could never be able to read it back) 174 | // 175 | // Note how the bitset object is not initially empty. That helps checking 176 | // that it isn't erroneously clear()ed by operator>>. 177 | 178 | 179 | std::ios::iostate masks[] = { 180 | std::ios::goodbit, 181 | std::ios::eofbit, 182 | std::ios::failbit, 183 | std::ios::eofbit | std::ios::failbit 184 | }; 185 | 186 | const std::string spaces = "\t\n "; //"\t\n\v\f "; 187 | 188 | const std::string long_string = get_long_string(); 189 | /*const*/ static std::string strings[] = { 190 | // NOTE: "const" gives the usual problems with Borland 191 | // (in Tests::stream_extractor instantiation) 192 | 193 | 194 | #if !(defined BOOST_BORLANDC \ 195 | && BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101))) 196 | // Borland 5.5.1 with RW library crashes 197 | // empty string 198 | std::string(""), 199 | // no bitset 200 | spaces, 201 | #endif 202 | // no bitset 203 | std::string("x"), 204 | std::string("\t xyz"), 205 | 206 | // bitset of size 1 207 | std::string("0"), 208 | std::string("1"), 209 | 210 | std::string(" 0 "), 211 | std::string(" 1 "), 212 | spaces + "1", 213 | "1" + spaces, 214 | spaces + "1" + spaces, 215 | std::string(" x1x "), 216 | std::string(" 1x "), 217 | 218 | // long bitset 219 | long_string, 220 | " " + long_string + " xyz", 221 | spaces + long_string, 222 | spaces + long_string + spaces 223 | }; 224 | 225 | 226 | //----------------------------------------------------- 227 | 228 | std::stringstream not_good_stream; 229 | not_good_stream << "test"; 230 | std::string sink; 231 | not_good_stream >> sink; // now the stream should be in eof state 232 | 233 | const std::size_t num_masks = sizeof(masks) / sizeof(masks[0]); 234 | const std::size_t num_strings = sizeof(strings) / sizeof(strings[0]); 235 | 236 | for (std::size_t mi = 0; mi < num_masks; ++mi) { 237 | for (std::size_t si = 0; si < num_strings; ++si) { 238 | 239 | const std::streamsize slen = (std::streamsize)(strings[si].length()); 240 | assert((std::numeric_limits::max)() >= (std::streamsize)(1+slen*2)); 241 | 242 | std::streamsize widths[] = { -1, 0, slen/2, slen, 1 + slen*2 }; 243 | std::size_t num_widths = sizeof(widths) / sizeof(widths[0]); 244 | 245 | for(std::size_t wi = 0; wi < num_widths; ++wi) { 246 | const std::streamsize w = widths[wi]; 247 | 248 | // test 0 - !good() stream 249 | { 250 | if(not_good_stream.good()) 251 | throw std::logic_error("Error in operator >> tests" 252 | " - please, double check"); 253 | bitset_type b(1, 15ul); // note: b is not empty 254 | not_good_stream.width(w); 255 | try { not_good_stream.exceptions(masks[mi]); } catch(...) {} 256 | std::string irrelevant; 257 | Tests::stream_extractor(b, not_good_stream, irrelevant); 258 | } 259 | // test 1a - (narrow) file stream 260 | { 261 | scoped_temp_file stf; 262 | bitset_type b(1, 255ul); 263 | { 264 | std::ofstream f(stf.path().string().c_str()); 265 | f << strings[si]; 266 | } 267 | 268 | std::ifstream f(stf.path().string().c_str()); 269 | f.width(w); 270 | f.exceptions(masks[mi]); 271 | Tests::stream_extractor(b, f, strings[si]); 272 | } 273 | #if !defined(BOOST_NO_STRINGSTREAM) 274 | // test 2a - stringstream 275 | { 276 | bitset_type b(1, 255ul); 277 | std::istringstream stream(strings[si]); 278 | stream.width(w); 279 | stream.exceptions(masks[mi]); 280 | Tests::stream_extractor(b, stream, strings[si]); 281 | } 282 | #endif 283 | 284 | #if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS) 285 | // test 1b - wchar_t file stream 286 | { 287 | scoped_temp_file stf; 288 | std::wstring wstr = widen_string(strings[si]); 289 | bitset_type b(1, 255ul); 290 | { 291 | std::basic_ofstream of(stf.path().string().c_str()); 292 | of << wstr; 293 | } 294 | 295 | std::basic_ifstream f(stf.path().string().c_str()); 296 | f.width(w); 297 | f.exceptions(masks[mi]); 298 | Tests::stream_extractor(b, f, wstr); 299 | } 300 | // test 2b - wstringstream 301 | { 302 | bitset_type b(1, 255ul); 303 | std::wstring wstr = widen_string(strings[si]); 304 | 305 | std::wistringstream wstream(wstr); 306 | wstream.width(w); 307 | wstream.exceptions(masks[mi]); 308 | Tests::stream_extractor(b, wstream, wstr); 309 | } 310 | #endif // BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS 311 | 312 | } 313 | } 314 | 315 | } // for ( mi = 0; ...) 316 | 317 | 318 | } 319 | //===================================================================== 320 | // << Any other tests go here >> 321 | // ..... 322 | 323 | } 324 | 325 | 326 | int 327 | main() 328 | { 329 | run_test_cases(); 330 | run_test_cases(); 331 | run_test_cases(); 332 | run_test_cases(); 333 | # ifdef BOOST_HAS_LONG_LONG 334 | run_test_cases< ::boost::ulong_long_type>(); 335 | # endif 336 | 337 | return boost::report_errors(); 338 | } 339 | -------------------------------------------------------------------------------- /test/dyn_bitset_unit_tests5.cpp: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------- 2 | // Copyright (c) 2001 Jeremy Siek 3 | // Copyright (c) 2003-2006 Gennaro Prota 4 | // 5 | // Copyright (c) 2015 Seth Heeren 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. 8 | // (See accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // ----------------------------------------------------------- 12 | 13 | #include "boost/config.hpp" 14 | #if !defined (BOOST_NO_STRINGSTREAM) 15 | # include 16 | #endif 17 | 18 | #include "bitset_test.hpp" 19 | #include 20 | #include 21 | 22 | 23 | // Codewarrior 8.3 for Win fails without this. 24 | // Thanks Howard Hinnant ;) 25 | #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x 26 | # pragma parse_func_templ off 27 | #endif 28 | 29 | 30 | #if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE 31 | # define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS 32 | #endif 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace { 42 | template 43 | struct SerializableType { 44 | boost::dynamic_bitset x; 45 | 46 | private: 47 | friend class boost::serialization::access; 48 | template void serialize(Archive &ar, const unsigned int) { 49 | ar & BOOST_SERIALIZATION_NVP(x); 50 | } 51 | }; 52 | 53 | template 54 | void test_serialization( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 55 | { 56 | SerializableType a; 57 | 58 | for (int i=0; i<128; ++i) 59 | a.x.resize(11*i, i%2); 60 | 61 | #if !defined (BOOST_NO_STRINGSTREAM) 62 | std::stringstream ss; 63 | 64 | // test serialization 65 | { 66 | OArchive oa(ss); 67 | oa << BOOST_SERIALIZATION_NVP(a); 68 | } 69 | 70 | // test de-serialization 71 | { 72 | IArchive ia(ss); 73 | SerializableType b; 74 | ia >> BOOST_SERIALIZATION_NVP(b); 75 | 76 | assert(a.x == b.x); 77 | } 78 | #else 79 | # error "TODO implement file-based test path?" 80 | #endif 81 | } 82 | 83 | template 84 | void test_binary_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) { 85 | test_serialization(); 86 | } 87 | 88 | template 89 | void test_xml_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) { 90 | test_serialization(); 91 | } 92 | } 93 | 94 | template 95 | void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) 96 | { 97 | test_binary_archive(); 98 | test_xml_archive(); 99 | } 100 | 101 | int main() 102 | { 103 | run_test_cases(); 104 | run_test_cases(); 105 | run_test_cases(); 106 | run_test_cases(); 107 | # ifdef BOOST_HAS_LONG_LONG 108 | run_test_cases< ::boost::ulong_long_type>(); 109 | # endif 110 | 111 | return boost::report_errors(); 112 | } 113 | -------------------------------------------------------------------------------- /test/test_ambiguous_set.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 James E. King III 3 | // 4 | // Permission to copy, use, modify, sell and distribute this software 5 | // is granted provided this copyright notice appears in all copies. 6 | // This software is provided "as is" without express or implied 7 | // warranty, and with no claim as to its suitability for any purpose. 8 | // 9 | // Distributed under the Boost Software License, Version 1.0. (See 10 | // accompanying file LICENSE_1_0.txt or copy at 11 | // http://www.boost.org/LICENSE_1_0.txt) 12 | // 13 | 14 | #include 15 | #include 16 | 17 | int main(int, char*[]) 18 | { 19 | boost::dynamic_bitset<> x(5); // all 0's by default 20 | x.set(1, 2); 21 | x.set(3, 1, true); 22 | x.set(2, 1, false); 23 | BOOST_TEST(!x.test(0)); 24 | BOOST_TEST( x.test(1)); 25 | BOOST_TEST(!x.test(2)); 26 | BOOST_TEST( x.test(3)); 27 | BOOST_TEST(!x.test(4)); 28 | 29 | return boost::report_errors(); 30 | } 31 | -------------------------------------------------------------------------------- /test/test_boost_hash.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2019 James E. King III 3 | // 4 | // Permission to copy, use, modify, sell and distribute this software 5 | // is granted provided this copyright notice appears in all copies. 6 | // This software is provided "as is" without express or implied 7 | // warranty, and with no claim as to its suitability for any purpose. 8 | // 9 | // Distributed under the Boost Software License, Version 1.0. (See 10 | // accompanying file LICENSE_1_0.txt or copy at 11 | // http://www.boost.org/LICENSE_1_0.txt) 12 | // 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main(int, char*[]) 20 | { 21 | typedef boost::dynamic_bitset bitset_type; 22 | const std::string long_string = 23 | "01001110101110110101011010000000000011110101101111111111"; 24 | const std::string long_string_prime_begin = 25 | "11001110101110110101011010000000000011110101101111111111"; 26 | const std::string long_string_prime_end = 27 | "01001110101110110101011010000000000011110101101111111110"; 28 | 29 | bitset_type zeroes(long_string.size(), 0); 30 | bitset_type stuff (long_string); 31 | bitset_type stupb (long_string_prime_begin); 32 | bitset_type stupe (long_string_prime_end); 33 | bitset_type ones (long_string.size(), 1); 34 | 35 | boost::hash bitset_hasher; 36 | std::set results; 37 | results.insert(bitset_hasher(zeroes)); 38 | results.insert(bitset_hasher(stuff)); 39 | results.insert(bitset_hasher(stupb)); 40 | results.insert(bitset_hasher(stupe)); 41 | results.insert(bitset_hasher(ones)); 42 | 43 | // if any hash is identical to another there will be less than 5 44 | BOOST_TEST_EQ(results.size(), 5); 45 | 46 | return boost::report_errors(); 47 | } 48 | -------------------------------------------------------------------------------- /test/test_lowest_bit.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2018 James E. King III 3 | // 4 | // Permission to copy, use, modify, sell and distribute this software 5 | // is granted provided this copyright notice appears in all copies. 6 | // This software is provided "as is" without express or implied 7 | // warranty, and with no claim as to its suitability for any purpose. 8 | // 9 | // Distributed under the Boost Software License, Version 1.0. (See 10 | // accompanying file LICENSE_1_0.txt or copy at 11 | // http://www.boost.org/LICENSE_1_0.txt) 12 | // 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int, char*[]) 19 | { 20 | for (boost::int32_t i = 1; i < 32; ++i) { 21 | BOOST_TEST_EQ(i, boost::detail::lowest_bit(1u << i)); 22 | } 23 | 24 | BOOST_TEST_EQ(2, boost::detail::lowest_bit(123456788)); 25 | BOOST_TEST_EQ(30, boost::detail::lowest_bit(static_cast(1507208177123328))); 26 | 27 | return boost::report_errors(); 28 | } 29 | -------------------------------------------------------------------------------- /test/test_std_hash.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2019 James E. King III 3 | // 4 | // Permission to copy, use, modify, sell and distribute this software 5 | // is granted provided this copyright notice appears in all copies. 6 | // This software is provided "as is" without express or implied 7 | // warranty, and with no claim as to its suitability for any purpose. 8 | // 9 | // Distributed under the Boost Software License, Version 1.0. (See 10 | // accompanying file LICENSE_1_0.txt or copy at 11 | // http://www.boost.org/LICENSE_1_0.txt) 12 | // 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | int main(int, char*[]) 22 | { 23 | typedef boost::dynamic_bitset bitset_type; 24 | const std::string long_string = 25 | "01001110101110110101011010000000000011110101101111111111"; 26 | 27 | bitset_type zeroes(long_string.size(), 0); 28 | bitset_type stuff (long_string); 29 | bitset_type ones (long_string.size(), 1); 30 | 31 | std::unordered_set bitsets; 32 | bitsets.insert(zeroes); 33 | bitsets.insert(stuff); 34 | bitsets.insert(ones); 35 | 36 | BOOST_TEST_EQ(bitsets.size(), 3); 37 | 38 | return boost::report_errors(); 39 | } 40 | --------------------------------------------------------------------------------