Compare commits

..

133 Commits

Author SHA1 Message Date
Gennaro Prota
66690c41d1 Merge branch 'develop' into experiments/antora 2025-07-22 16:29:42 +02:00
Gennaro Prota
e475e3052f Fix a typo in the documentation of operator>>=() 2025-07-22 16:28:58 +02:00
Gennaro Prota
7f2d9b405f Shorten some brief descriptions in the docs
This simply separates the first sentence from the rest with a blank
line, so that MrDocs takes just the first sentence as brief description.
2025-07-22 16:27:19 +02:00
Gennaro Prota
472fcfe7f8 Add two missing spaces in a documentation comment 2025-07-22 16:17:47 +02:00
Gennaro Prota
224c1cf590 Merge branch 'develop' into experiments/antora 2025-07-22 12:40:31 +02:00
Gennaro Prota
6c69d92398 Also exclude bit_appender from the MrDocs documentation 2025-07-22 12:39:28 +02:00
Gennaro Prota
91b957bbbb Remove a pair of unneeded parentheses 2025-07-22 12:32:04 +02:00
Gennaro Prota
ad9b1a439e Also trigger CI for experiments/** 2025-07-21 18:42:12 +02:00
Gennaro Prota
06d510fca2 Set version for antora-cpp-reference-extension 2025-07-21 18:38:40 +02:00
Gennaro Prota
f01dcbe60b Fix nav.adoc 2025-07-18 19:30:56 +02:00
Gennaro Prota
757939f082 Add a few links to the reference in the documentation index 2025-07-18 19:29:58 +02:00
Gennaro Prota
4fee7e5a77 Add doc/package.json and doc/package-lock.json 2025-07-17 10:46:06 +02:00
Gennaro Prota
31504199cd Exclude old, failing versions of Clang and GCC from CI 2025-07-17 10:45:57 +02:00
Gennaro Prota
2357cd92b7 Also build the documentation in the CI workflow 2025-07-16 16:53:16 +02:00
James E. King III
a5398355ac Implement Boost.CI 2025.07 reusable workflow
This moves the majority of build logic into Boost.CI with configuration
options for consumers.  By moving build logic into Boost.CI we can fix
build issues faster for everyone.
2025-07-14 19:30:32 +02:00
Gennaro Prota
43ba4c9ca4 Rethrow any exception coming from the underlying vector, in the stream extractor 2025-07-14 19:30:32 +02:00
Gennaro Prota
e9d0f7ff0e Delete unary operator&() for dynamic_bitset::reference
Reason: That's better than declaring it as private and leaving it
undefined.
2025-07-14 19:30:32 +02:00
Gennaro Prota
8da24d5377 Don't add a semicolon after "BOOST_RETHROW"
Reason: When exceptions are enabled, the semicolon is already included
in the macro expansion, and the resulting second semicolon (empty
statement) may give compiler warnings. Note how we added braces, for
when exceptions are disabled and the macro has an empty replacement
list.
2025-07-14 19:30:31 +02:00
Gennaro Prota
71f8a37dc0 Add a missing blank line 2025-07-14 19:30:31 +02:00
Gennaro Prota
32dca8ac20 Remove an unnecessary constructor definition 2025-07-14 19:30:31 +02:00
Gennaro Prota
f684596b1d Remove an unnecessary implementation detail 2025-07-14 19:30:31 +02:00
Gennaro Prota
da2768d346 Add a definition for the copy constructor of dynamic_bitset::reference
Reason: Implicit definition is deprecated, because the class has a
user-declared copy assignment operator.

This closes issue #62.
2025-07-14 19:30:31 +02:00
Gennaro Prota
2928206d63 Make scoped_temp_file non-copyable, as it should 2025-07-14 19:30:31 +02:00
Gennaro Prota
c6f94b52ca Remove a nonsensical typedef 2025-07-14 19:30:31 +02:00
Gennaro Prota
367790225b Don't use lowerCamelCase for template type parameters 2025-07-14 19:30:31 +02:00
Gennaro Prota
fea6e4eecb Copy edit a comment 2025-07-14 19:30:31 +02:00
Gennaro Prota
26c9b60e36 Remove a few unneeded permission notices 2025-07-14 19:30:31 +02:00
Gennaro Prota
2675e65ce8 Port the documentation to MrDocs and Antora 2025-07-14 19:30:25 +02:00
Gennaro Prota
04b105c78f Reformat all the C++ code (with ClangFormat) 2025-07-07 15:34:23 +02:00
Gennaro Prota
d0f0182b3c Add a ClangFormat configuration file
This specifies a more readable style with respect to the existing one.
I'll reformat the code with the next commit.
2025-07-07 15:34:23 +02:00
Gennaro Prota
db21469d77 Move all the function definitions to a separate file
Reason: Improving readability of the class template declaration.

This separation was not originally possible due to limitations in older
compilers (see the removed comment at the start of the definition of
dynamic_bitset), but is now feasible.
2025-07-07 15:34:23 +02:00
Gennaro Prota
0ae6dd4e0e Leverage core::popcount() in the implementation of count()
Reason: This significantly simplifies the code, replacing a previous
complex and error-prone implementation.
2025-07-07 15:34:23 +02:00
Gennaro Prota
6477f68fb3 Fix some inconsistent placement of const qualifiers 2025-07-07 15:34:23 +02:00
Gennaro Prota
a35c951953 Assert on the precondition to pop_back() 2025-07-07 15:34:23 +02:00
Gennaro Prota
499916234e Make the swap() functions noexcept 2025-07-07 15:34:23 +02:00
Gennaro Prota
459df8c817 Remove a misleading comment 2025-07-07 15:34:23 +02:00
Gennaro Prota
0a95b0295a Remove a redundant assertion
We already assert that the two bitsets have the same size and, since
they have the same block_type, that implies they have the same number of
blocks.
2025-07-07 15:34:23 +02:00
Gennaro Prota
f33ec5bda7 Remove a top-level const qualifier for a function parameter 2025-07-07 15:34:15 +02:00
Gennaro Prota
ad57ed3f34 Add a missing const qualifier in a test function 2025-07-07 15:34:03 +02:00
Gennaro Prota
3d4661e2a8 Use BOOST_TEST(), not assert(), for test cases 2025-07-07 15:33:55 +02:00
Gennaro Prota
d4edc53c02 Remove other workarounds for obsolete compilers 2025-07-07 15:33:46 +02:00
Gennaro Prota
4f25dff8b2 Don't misuse the term "precondition" in the documentation
If you guarantee some behavior, e.g. throwing an exception, it's not
really a precondition.
2025-07-07 15:33:36 +02:00
Gennaro Prota
bb4ac379f9 Clean up detail/lowest_bit.hpp (mostly, reformat) 2025-07-07 15:33:26 +02:00
Gennaro Prota
060efe9166 Remove a naive comment
If you are asserting on it at the beginning of the function, it's
clearly a precondition :-).
2025-07-07 15:33:17 +02:00
Gennaro Prota
8d2b37a8f8 Replace the references to the SGI documentation
This commit just removes all the links to the SGI documentation and
replaces most of them with links to cppreference.com. The SGI docs were
likely used by Jeremy Siek at the time because they were a good and
clear reference. But we have cppreference.com now, which is much better.
And, in the event it disappears, we can still revert this commit.

Some links have simply been removed (e.g. those to the documentation of
basic_string, which really didn't seem opportune).
2025-07-07 15:33:10 +02:00
Gennaro Prota
cc2e543137 Remove inconsistent uses of title case 2025-07-07 15:33:01 +02:00
Gennaro Prota
7ee158b972 Remove trailing whitespace 2025-07-07 15:32:51 +02:00
Gennaro Prota
4339073d77 Remove an unneeded #include directive in a test file 2025-07-07 15:32:43 +02:00
Gennaro Prota
3bf84c9233 Remove a tab character in a test file 2025-07-07 15:32:32 +02:00
Gennaro Prota
702192bf52 Remove a superfluous #include directive 2025-07-07 15:32:24 +02:00
Gennaro Prota
2f497d44d7 Remove superfluous parentheses around a macro name 2025-07-07 15:32:15 +02:00
Gennaro Prota
ff6fc1f065 Copy edit the readme
Note how I removed the "Directories" paragraph, as it just stated the
obvious.
2025-07-07 15:32:05 +02:00
Gennaro Prota
96fad2cc08 Remove an unused, junk function template 2025-07-07 15:31:58 +02:00
Gennaro Prota
c6ecae2129 Consistently use BOOST_ASSERT() in the implementation
Note: Not in the unit tests, which better do without the dependency.
2025-07-07 15:31:48 +02:00
Gennaro Prota
a1fe5493c7 Remove a workaround for CodeWarrior 8 2025-07-07 15:31:16 +02:00
Gennaro Prota
b6a3959648 Remove a spurious #undef directive
The #undef'd macro wasn't actually defined anywhere.
2025-07-07 15:31:05 +02:00
Gennaro Prota
3aad037ed1 Declare some internal details as private
They had been accidentally made public.
2025-07-07 15:30:59 +02:00
Gennaro Prota
a6096f898e Remove some redundant access specifiers 2025-07-07 15:30:52 +02:00
Gennaro Prota
c6e1912392 Remove a hopefully outdated workaround 2025-07-07 15:30:43 +02:00
Gennaro Prota
b1e431c8e4 Remove a nonsensical usage of boost::addressof
Because `dynamic_bitset` doesn't overload unary `operator &`.
2025-07-07 15:30:24 +02:00
Gennaro Prota
ec4fce5d3e Fix the initial description in the documentation
This also aligns it with meta/libraries.json.
2025-07-07 15:30:11 +02:00
Gennaro Prota
c560925513 Update my email address etc. in the documentation 2025-07-07 15:30:01 +02:00
Gennaro Prota
79ebe76301 Fix the metadata in libraries.json
The main fix, here, is not stating that dynamic_bitset is a container.
It isn't (at least in the C++ meaning of the term), as specified in the
documentation.

I'm also taking over as a maintainer, so I added my email address.
2025-07-07 15:29:39 +02:00
Gennaro Prota
6c7c6618e6 Clean up all the #include sections
This commit:

- Sorts the #include directives: The #includes of the ""-form come
  first, those of the <>-form come later (this helps checking if any
  include file is not self-sufficient); in each of the two groups, the
  names of the headers or source files are sorted alphabetically (this
  eases searching for a specific #include and avoids duplicates).

- Uses the ""-form when including Boost files; using the <>-form is a
  relic of the past. This was even discussed on the developers list many
  years ago and led to core issue 370. Note that some parts of
  DynamicBitset were already using the ""-form and that has never caused
  any problem, AFAIK.

- Removes some comments attached to the directives themselves which
  seemed pretty useless and prone to get out of sync.
2025-07-07 15:29:28 +02:00
Gennaro Prota
2852d27363 Remove all support for pre-standard iostreams
Reason: When I re-implemented dynamic_bitset, GCC 2.95 was still around
and its library still only implemented pre-standard iostreams, so I
added that support. But I'm pretty sure no one needs it, now.
2025-07-07 15:29:13 +02:00
Gennaro Prota
179d719c92 Remove a flawed "example" (timing_tests.cpp)
Reason: That file was intended as a benchmark, but it was poorly
constructed. It did not pre-load the cache, did not run the tested code
multiple times, and did not follow standard benchmarking practices. As
such, it was misleading and not useful.
2025-07-07 15:28:39 +02:00
greg7mdp
688a99f54a Fix typo. 2025-03-29 08:02:48 -04:00
Unix&Me
b96250c3c6 simplify push_back logic 2024-12-28 16:25:41 -05:00
James E. King III
d6eb91388f Update CI to 2024.12 spec, update README 2024-12-28 21:25:17 +00:00
Anthony Eden
41d08970cd Support stateful allocators 2024-12-24 09:29:42 -05:00
James E. King III
cd59d325d3 Enable branch coverage. 2024-11-30 19:43:12 +00:00
twomice
34f55c74b1 Implement find_first(pos). 2024-11-26 13:59:18 -05:00
James E. King III
b33c19e05c Given GHA busted ubuntu-18.04 containers, those build jobs have been
removed.  Others have been updated to move forward.
2024-11-26 18:56:51 +00:00
Alexander Grund
b3c78809c0 GHA: Reenable CMake jobs 2024-11-26 12:14:09 -05:00
Alexander Grund
3347ea317c GHA: Add CMake subdir test 2024-11-26 12:14:09 -05:00
James E. King III
8ad7522ca0 Fix documentation links in the README 2024-11-25 22:27:27 +00:00
James E. King III
4eada1889f Appveyor: move to cppalliance account
- Removed MINGW64 run from Appveyor, as it is done in GHA.
- Updated README to use badges from cppalliance org.
2024-11-25 22:21:52 +00:00
James E. King III
9f5a992ffa Remove GHA macos-12 as it is not offered any more. 2024-11-25 20:07:45 +00:00
James E. King III
0b9a081d97 Refresh GitHub Actions and Appveyor CI
Moved baseline to C++11 due to our dependencies.

- Remove C++98 and C++03 from CI and mark C++11 baseline
- Remove duplicate jobs between Appveyor and GHA
- Disable CMake GHA jobs for now; broken
2024-11-25 18:59:55 +00:00
Rene Rivera
053fadace9 Update build deps. 2024-11-24 06:48:02 -05:00
Rene Rivera
2cbf3ad7d8 Move inter-lib dependencies to a project variable and into the build targets. 2024-11-24 06:48:02 -05:00
Rene Rivera
3bb682db62 Update copyright dates. 2024-11-24 06:48:02 -05:00
Rene Rivera
76b4bba9c2 Bump B2 require to 5.2 2024-11-24 06:48:02 -05:00
Rene Rivera
11d94f6794 Add requires-b2 check to top-level build file. 2024-11-24 06:48:02 -05:00
Rene Rivera
0231a500ed Add missing import-search for cconfig/predef checks. 2024-11-24 06:48:02 -05:00
Rene Rivera
7939bf7ae6 Add missing b2 testing module import. 2024-11-24 06:48:02 -05:00
Rene Rivera
1eed20166e Switch to library requirements instead of source. As source puts extra source in install targets. 2024-11-24 06:48:02 -05:00
Rene Rivera
1e9aa506d0 Make the library modular usable. 2024-11-24 06:48:02 -05:00
Alexander Grund
8e20aa1462 Fix ccache saving on cache hit (#70)
See boostorg/boost-ci#166
2022-06-24 08:58:29 -07:00
akr
d4be7a4fcb Changed the order of at() 2022-05-02 20:38:40 -04:00
akr
29e1d40e88 Added std::out_of_range tests 2022-05-02 20:38:40 -04:00
akr
ccca25537a Updated docs 2022-05-02 20:38:40 -04:00
akr
12be4b4464 Added tests 2022-05-02 20:38:40 -04:00
akr
b15fd0075f Added at(size_type) 2022-05-02 20:38:40 -04:00
James E. King III
abd6417090 re-add mingw to ci 2022-04-24 21:16:37 -04:00
James E. King III
eb3f18086e Fix badges in readme for develop 2022-04-15 16:21:30 -04:00
James E. King III
c811f468cd align CI to boost-ci standard and update README 2022-04-15 12:40:54 -04:00
Sam Darwin
709a03b9e2 Update GitHub Actions CI file (#61) 2021-08-04 07:07:10 -07:00
Peter Dimov
11d85403b9 Regenerate CMakeLists.txt 2021-05-30 07:28:07 +03:00
Sam Darwin
296f902453 Add GitHub Actions config [ci skip] (#60) 2021-03-03 18:26:18 -08:00
Sam Darwin
a16a1c3afa add drone config [ci skip] (#57) 2021-03-03 18:25:37 -08:00
Edward Diener
66a956b114 Add "cxxstd" json field 2021-01-19 17:48:52 -05:00
Glen Fernandes
b59fc97a67 Use core/allocator_access for allocator use 2020-05-25 22:57:13 -04:00
Andrey Semashev
4a38853898 Avoid using deprecated headers to silence compiler warnings. (#56)
The warnings are generated by boost/detail/iterator.hpp and
boost/detail/no_exceptions_support.hpp. Also, updated location of
addressof.hpp.
2020-05-13 06:44:47 -07:00
joprodrigues
54b15ad171 Improvement to m_do_find_from (#55)
Use find_if to inside find next bit
2020-04-26 10:11:36 -04:00
Edward Diener
ffff25ac00 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. (#54) 2020-04-16 07:47:58 -07:00
Glen Fernandes
3e0107909b Replace Block(~0) with a max_limit<Block>::value 2020-01-22 07:41:06 -05:00
Glen Fernandes
8359a80feb Make DynamicBitset no longer depend on Serialization (#50) 2019-09-30 15:29:43 -04:00
James E. King III
db5da12bcd Update CI
This fixes #41
2019-06-23 20:19:38 -04:00
Miutsuru kariya
ab192ca5f1 Make default constructor non-explicit (#48)
It is better to support copy-initialization with default constructor. cf. LWG Issue 2193. Default constructors for standard library containers are explicit.
2019-06-12 19:45:11 -04:00
James E. King III
26918f80d5 Add support for std::hash and unit tests for hashing 2019-06-07 13:55:57 -04:00
Alexey Stukalov
229bced733 hash_value() for dynamic_bitset (support boost::hash) 2019-06-07 13:55:57 -04:00
Glen Fernandes
ccb380a1bc Switch from deprecated Test to LightweightTest 2019-06-07 07:02:31 -04:00
Sam Day
4de44e9112 Add basic CMake support. 2019-06-06 11:37:47 -04:00
James E. King III
3f650f50c3 Since coverity with gcc hangs, trying clang 2019-04-26 12:56:07 -04:00
James E. King III
b64e20079c Fix coverity scan job 2019-04-26 09:48:03 -04:00
Andrey Semashev
83bdf5a335 Reenabled popcnt for MSVC, improved perf by leveraging ILP.
On MSVC and compatible compilers popcnt is now enabled if it is known at
compile time that the target CPU supports popcnt instruction. Unfortunately,
MSVC does not have a predefined macro specifically for popcnt, so we have
to test for AVX instead. __POPCNT__ is still tested in case clang or user
defines it.

For MSVC, the 64-bit popcount is now also implemented on 32-bit targets by
issuing two 32-bit popcnt instructions. For gcc and compatible compilers,
16-bit popcount implementation is provided, which is better than the generic
popcount implementation, but still slower than byte-wise do_count.

The do_count algorithm implementations have been improved by leveraging
instruction level parallelism better, which gives 0 to 27% improvement and
no regressions.

Also made code formatting more consistent and reduced code duplication between
do_count implementations.
2019-04-26 08:55:53 -04:00
Tinko Bartels
c747bec057 Change sgi/stl links to boost.org. 2019-04-23 13:32:20 -04:00
James E. King III
f506b99f70 Update CI and change boost/timer deprecated use 2019-04-23 10:40:34 -04:00
Tinko Bartels
1b8b128f29 Replaced links to sgi.com with links to a mirror. 2019-04-22 12:20:38 -04:00
James E. King III
91625cece1 Disable hardware supported popcount on MSVC.
- the new implementation failed to check for hardware support
- the behavior was undefined on platforms without SSE4
2019-02-22 08:36:12 -05:00
James E. King III
a580c496fa fix set() ambiguity with range based call and default value 2018-11-03 16:45:29 -04:00
James E. King III
1ca15c5fcd Enhance CI with libc++ and VC2017 strict jobs 2018-11-03 15:54:53 -04:00
James E. King III
512ac37529 Enhance Travis CI build coverage 2018-10-28 10:42:35 -04:00
James E. King III
8e265c49f8 cleanup pending and detail headers 2018-10-21 12:44:12 -04:00
Evgeny Shulgin
a449a11a80 Add set/reset/flip functions to change sequences (#27)
* Add set(pos, len) function to change sequences
* Add reset(pos, len) function to clear sequences
* Add flip(pos, len) function to flip sequences
* Add custom range operations
2018-10-12 08:07:01 -04:00
James E. King III
a0735943f2 Merge branch 'master' into develop 2018-10-12 11:47:12 +00:00
Glen Fernandes
8fe1db1b08 Correct e-mail address 2018-09-23 08:55:34 -04:00
Glen Fernandes
d7d6555f85 Correct e-mail address 2018-09-05 08:11:50 -04:00
Evgeny Shulgin
a90fe08934 Add hardware supported popcount 2018-09-01 21:56:57 -04:00
James E. King III
b944aa3008 fix broken ci jobs in travis 2018-07-14 20:51:19 +00:00
James E. King III
759af5e853 Fix coverity badges in readme 2018-07-04 08:05:54 -04:00
James E. King III
7b6379a356 Add CI framework used in a number of other repositories:
- travis with valgrind, cppcheck, ubsan, codecov, covscan (future)
  - appveyor with MSVC 2010 through 2017, cygwin 32/64, mingw 32/64
  - README, LICENSE, etc.
2018-07-04 07:49:11 -04:00
47 changed files with 9930 additions and 7210 deletions

97
.appveyor.yml Normal file
View File

@@ -0,0 +1,97 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2017 - 2019 James E. King III
# Copyright 2019 - 2021 Alexander Grund
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
#
# Generic Appveyor build script for boostorg repositories
# See: https://github.com/boostorg/boost-ci/
#
# Instructions for customizing this script for your library:
#
# 1. Customize the compilers and language levels you want.
# 2. If you have more than include/, src/, test/, example/, examples/,
# benchmark/ or tools/ directories, set the environment variable DEPINST.
# For example if your build uses code in "bench/" and "fog/" directories:
# - DEPINST: --include bench --include fog
# 3. Enable pull request builds in your boostorg/<library> account.
#
# That's it - the script will do everything else for you.
#
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /bugfix\/.*/
- /feature\/.*/
- /fix\/.*/
- /pr\/.*/
skip_commits:
files:
- LICENSE
- meta/*
- README.md
matrix:
fast_finish: false
# Adding MAYFAIL to any matrix job allows it to fail but the build stays green:
allow_failures:
- MAYFAIL: true
environment:
global:
B2_CI_VERSION: 1
GIT_FETCH_JOBS: 4
# see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
# to use the default for a given environment, comment it out; recommend you build debug and release however:
# on Windows it is important to exercise all the possibilities, especially shared vs static, however most
# libraries that care about this exercise it in their Jamfiles...
B2_ADDRESS_MODEL: 32,64
B2_LINK: shared,static
# B2_THREADING: threading=multi,single
B2_VARIANT: release
matrix:
- FLAVOR: Visual Studio 2017 C++2a Strict
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXFLAGS: -permissive-
B2_CXXSTD: 2a
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2017 C++14/17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXSTD: 14,17
B2_TOOLSET: msvc-14.1
- FLAVOR: cygwin (32-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin\bin;
B2_ADDRESS_MODEL: 32
B2_CXXSTD: 11,14,1z
B2_TOOLSET: gcc
- FLAVOR: cygwin (64-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 11,14,1z
B2_TOOLSET: gcc
install:
- git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned
# Copy ci folder if not testing Boost.CI
- if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci
- rmdir /s /q C:\boost-ci-cloned
- ci\appveyor\install.bat
build: off
test_script: ci\build.bat

168
.clang-format Normal file
View File

@@ -0,0 +1,168 @@
# ============================================================================
# Copyright 2025 Gennaro Prota.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# ============================================================================
AccessModifierOffset: -4
AlignAfterOpenBracket: AlwaysBreak
AlignArrayOfStructures: Left
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
AlignConsecutiveBitFields: AcrossEmptyLinesAndComments
AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: AllDefinitions
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros: [ ]
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Never
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: true
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: ''
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Always
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros: [ ]
IfMacros: [ ]
IncludeBlocks: Regroup
IncludeCategories:
- Regex: 'top_level_namespace.hpp'
Priority: 0
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 1
CaseSensitive: false
IncludeIsMainRegex: ''
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: false
IndentPPDirectives: AfterHash
IndentExternBlock: AfterExternBlock
IndentRequires: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: Wrapped
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Middle
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceAroundPointerQualifiers: Both
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Always
SpacesInConditionalStatement: true
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: true
SpacesInSquareBrackets: true
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros: [ ]
StatementMacros: [ ]
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros: [ ]
# Local Variables:
# mode: yaml
# End:
# vim: set ft=yaml:

31
.codecov.yml Normal file
View File

@@ -0,0 +1,31 @@
# Copyright 2019 - 2021 Alexander Grund
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
#
# Sample codecov configuration file. Edit as required
codecov:
max_report_age: off
require_ci_to_pass: yes
notify:
# Increase this if you have multiple coverage collection jobs
after_n_builds: 2
wait_for_ci: yes
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
# Change how pull request comments look
comment:
layout: "reach,diff,flags,files,footer"
# Ignore specific files or folders. Glob patterns are supported.
# See https://docs.codecov.com/docs/ignoring-paths
ignore:
- libs/dynamic_bitset/test/
- test/

111
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,111 @@
#
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 Andrey Semashev
# Copyright 2021-2024 Alexander Grund
# Copyright 2022-2025 James E. King III
# Copyright 2023 Alan de Freitas
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
#
# This workflow uses the Boost.CI reusable workflow which builds a variety of
# configurations of your project, runs tests, and generates code coverage reports.
#
# To use it, copy this file into your repository as `.github/workflows/ci.yml` and
# customize it appropriately.
#
---
name: Boost.CI
on:
pull_request:
push:
branches:
- master
- develop
- bugfix/**
- feature/**
- fix/**
- pr/**
- experiments/**
paths-ignore:
- LICENSE
- meta/**
- README.md
jobs:
call-boost-ci:
name: Run Boost.CI
uses: boostorg/boost-ci/.github/workflows/reusable.yml@master
with:
# These compilers fail.
exclude_compiler: 'clang-3.5,clang-3.6,clang-3.7,clang-3.8,gcc-4.8,gcc-4.9'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
antora:
name: Antora docs
strategy:
matrix:
include:
- { name: Windows, os: windows-latest }
- { name: Ubuntu, os: ubuntu-latest }
- { name: macOS, os: macos-latest }
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
steps:
- name: Install packages
uses: alandefreitas/cpp-actions/package-install@v1.8.8
with:
apt-get: git cmake
- name: Clone Boost.DynamicBitset
uses: actions/checkout@v4
- name: Clone Boost
uses: alandefreitas/cpp-actions/boost-clone@v1.8.8
id: boost-clone
with:
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
boost-dir: ../boost-source
scan-modules-dir: .
scan-modules-ignore: dynamic_bitset
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Setup Ninja
if: runner.os == 'Windows'
uses: seanmiddleditch/gha-setup-ninja@v5
- name: Build Antora docs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global --add safe.directory "$(pwd)"
cd ..
BOOST_SRC_DIR="$(pwd)/boost-source"
export BOOST_SRC_DIR
cd dynamic_bitset
cd doc
bash ./build_docs.sh
# Antora returns zero even if it fails, so we check if the site directory exists.
if [ ! -d "build/site" ]
then
echo "Antora build failed"
exit 1
fi
- name: Create Antora docs artifact
uses: actions/upload-artifact@v4
with:
name: antora-docs-${{ matrix.name }}
path: doc/build/site

55
CMakeLists.txt Normal file
View File

@@ -0,0 +1,55 @@
# Generated by `boostdep --cmake dynamic_bitset`
# Copyright 2020 Peter Dimov
# Copyright 2025 Gennaro Prota
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_dynamic_bitset VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_dynamic_bitset INTERFACE)
add_library(Boost::dynamic_bitset ALIAS boost_dynamic_bitset)
target_include_directories(boost_dynamic_bitset INTERFACE include)
if (NOT DYNAMIC_BITSET_MRDOCS_BUILD)
target_link_libraries(boost_dynamic_bitset
INTERFACE
Boost::assert
Boost::config
Boost::container_hash
Boost::core
Boost::integer
Boost::move
Boost::static_assert
Boost::throw_exception
)
endif()
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
if (DYNAMIC_BITSET_MRDOCS_BUILD)
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
# Create a temporary source file that includes boost/dynamic_bitset.hpp.
set(TEMP_CPP_FILE "${CMAKE_CURRENT_BINARY_DIR}/dynamic_bitset_for_mrdocs.cpp")
file(WRITE ${TEMP_CPP_FILE} "// This file is generated automatically by CMake\n\n")
file(APPEND ${TEMP_CPP_FILE} "#include \"boost/dynamic_bitset.hpp\"\n")
# Create a custom target for MrDocs.
add_library(dynamic_bitset_mrdocs_target ${TEMP_CPP_FILE})
# Set any other target properties here.
target_include_directories(dynamic_bitset_mrdocs_target PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(dynamic_bitset_mrdocs_target PRIVATE boost_dynamic_bitset)
file(GLOB BOOST_MODULE_PATHS "$ENV{BOOST_SRC_DIR}/libs/*/include")
target_include_directories(dynamic_bitset_mrdocs_target PRIVATE ${BOOST_MODULE_PATHS})
# Don't create any other targets.
return()
endif()

View File

@@ -1,3 +0,0 @@
# Empty Jamfile because the super project still expects one to appear here.
# Can be deleted once 'status/Jamfile.v2' has been updated in the super
# project.

23
LICENSE Normal file
View File

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

25
README.md Normal file
View File

@@ -0,0 +1,25 @@
DynamicBitset, part of the [Boost C++ Libraries](https://github.com/boostorg), is a bit vector similar to std::bitset but dynamically resizable.
### License
Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
### Properties
* C++11
* Header-only
### Build status
<!-- boost-ci/tools/makebadges.sh --project dynamic_bitset --appveyor n7bki5ka3v918r5r --codecov PVG5jth1ez --coverity 16167 -->
| Branch | GitHub Actions | AppVeyor | Coverity Scan | Codecov | Deps | Docs | Tests |
| :-------------: | -------------- | -------- | ------------- | ------- | ---- | ---- | ----- |
| [`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)
| [`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)
### More information
* [Ask questions](https://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-dynamic_bitset).
* [Report bugs](https://github.com/boostorg/dynamic_bitset/issues): Be sure to mention the Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good, as well.
* Submit your patches as pull requests against the **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).
* 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.

30
build.jam Normal file
View File

@@ -0,0 +1,30 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/container_hash//boost_container_hash
/boost/core//boost_core
/boost/integer//boost_integer
/boost/move//boost_move
/boost/static_assert//boost_static_assert
/boost/throw_exception//boost_throw_exception ;
project /boost/dynamic_bitset
: common-requirements
<include>include
;
explicit
[ alias boost_dynamic_bitset : : : : <library>$(boost_dependencies) ]
[ alias all : boost_dynamic_bitset example test ]
;
call-if : boost-library dynamic_bitset
;

21
doc/antora.yml Normal file
View File

@@ -0,0 +1,21 @@
# ============================================================================
# Copyright 2025 Gennaro Prota.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# ============================================================================
name: dynamic_bitset
version: ~
title: Boost.DynamicBitset
start_page: index.adoc
asciidoc:
attributes:
source-language: asciidoc@
table-caption: false
nav:
- modules/ROOT/nav.adoc
ext:
cpp-reference:
config: doc/mrdocs.yml

28
doc/build_docs.sh Executable file
View File

@@ -0,0 +1,28 @@
#! /bin/sh --
# ============================================================================
# Copyright 2023 Alan de Freitas.
# Copyright 2025 Gennaro Prota.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# ============================================================================
set -eu
if [ $# -eq 0 ]
then
echo "No playbook supplied, using default playbook."
PLAYBOOK="local-playbook.yml"
else
PLAYBOOK=$1
fi
echo "Installing npm dependencies..."
npm ci
echo "Building docs in custom dir..."
PATH="$(pwd)/node_modules/.bin:${PATH}"
export PATH
npx antora --clean --fetch "$PLAYBOOK" --stacktrace --log-level all
echo "Done"

56
doc/local-playbook.yml Normal file
View File

@@ -0,0 +1,56 @@
# ============================================================================
# Copyright 2023 Alan de Freitas.
# Copyright 2025 Gennaro Prota.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# ============================================================================
#
# An antora playbook used for local development.
# The playbook includes Boost.DynamicBitset as its only component.
# ----------------------------------------------------------------------------
site:
title: Boost.DynamicBitset
url: https://antora.cppalliance.org/develop/lib/doc
start_page: dynamic_bitset::index.adoc
robots: allow
keys:
repo_url: 'https://github.com/boostorg/dynamic_bitset'
content:
sources:
- url: ..
start_path: doc
edit_url: 'https://github.com/boostorg/dynamic_bitset/edit/{refname}/{path}'
ui:
bundle:
url: https://github.com/boostorg/website-v2-docs/releases/download/ui-master/ui-bundle.zip
snapshot: true
antora:
extensions:
- require: '@antora/lunr-extension' # https://gitlab.com/antora/antora-lunr-extension
index_latest_only: true
- require: '@cppalliance/antora-cpp-tagfiles-extension'
cpp-tagfiles:
using-namespaces:
- 'boost::'
- require: '@cppalliance/antora-cpp-reference-extension'
version: 'develop'
dependencies:
- name: 'boost'
repo: 'https://github.com/boostorg/boost.git'
tag: 'develop'
variable: 'BOOST_SRC_DIR'
system-env: 'BOOST_SRC_DIR'
asciidoc:
attributes:
# Enable pagination
page-pagination: ''
extensions:
- '@cppalliance/asciidoctor-boost-links'
- '@asciidoctor/tabs'

10
doc/modules/ROOT/nav.adoc Normal file
View File

@@ -0,0 +1,10 @@
// ===========================================================================
// Copyright 2025 Gennaro Prota.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// ===========================================================================
* xref:index.adoc[]
* xref:reference:boost/dynamic_bitset.adoc[Reference]

View File

@@ -0,0 +1,79 @@
// ===========================================================================
// Copyright 2025 Gennaro Prota.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// ===========================================================================
= Boost.DynamicBitset
Boost.DynamicBitset is a portable library that provides a set of bits.
The set
(xref:reference:boost/dynamic_bitset.adoc#boost-dynamic_bitset[dynamic_bitset])
provides access to the value of individual bits via
xref:reference:boost/dynamic_bitset/operator_subs-08.adoc[operator[\]] and
provides all of the bitwise operators that one can apply to builtin integers,
such as xref:reference:boost/operator_bitand.adoc[operator&] and
xref:reference:boost/dynamic_bitset/operator_lshift.adoc[operator<<]. The number
of bits can change at runtime.
`dynamic_bitset` is nearly identical to `std::bitset`. The difference is that
the size of a `dynamic_bitset` (the number of bits) can change at runtime,
whereas the size of a `std::bitset` is specified at compile-time through an
integer template parameter.
The main problem that `dynamic_bitset` is designed to solve is that of
representing a subset of a finite set. Each bit represents whether an element of
the finite set is in the subset or not. As such the bitwise operations of
`dynamic_bitset`, such as `operator&` and `operator|`, correspond to set
operations, such as intersection and union.
== Definitions
Each bit represents either the Boolean value `true` or `false` (1 or 0). To set
a bit is to assign it 1. To clear or reset a bit is to assign it 0. To flip a
bit is to change the value to 1 if it was 0 and to 0 if it was 1. Each bit has a
non-negative position. A bitset `x` contains `x.size()` bits, with each bit
assigned a unique position in the range `[0, x.size())`. The bit at position 0
is called the least significant bit and the bit at position `size() - 1` is the
most significant bit. When converting an instance of `dynamic_bitset` to or from
an unsigned long `n`, the bit at position `i` of the bitset has the same value
as `(n >> i) & 1`.
== Rationale
`dynamic_bitset` is not a <a
href="https://en.cppreference.com/w/cpp/named_req/Container.html">Container</a>
and does not provide iterators for the following reason:
A container with a proxy reference type can not fulfill the container
requirements as specified in the C++ standard (unless one resorts to strange
iterator semantics). `std::vector<bool>` has a proxy reference type and does not
fulfill the container requirements and as a result has caused many problems. One
common problem is when people try to use iterators from `std::vector<bool>` with
a standard algorithm such as `std::search()`. The `std::search()` requirements
say that the iterator must be a LegacyForwardIterator, but
`std::vector<bool>::iterator` does not meet this requirement because of the
proxy reference. Depending on the implementation, they may or not be a compile
error or even a run-time error due to this misuse. For further discussion of the
problem see "Effective STL" by Scott Meyers. So `dynamic_bitset` tries to avoid
these problems by not pretending to be a container.
Some people prefer the name "toggle" to "flip". The name "flip" was chosen
because that is the name used in `std::bitset`. In fact, most of the function
names for `dynamic_bitset` were chosen for this reason.
`dynamic_bitset` does not throw exceptions when a precondition is violated (as
is done in `std::bitset`). Instead `BOOST_ASSERT()` is used. See the guidelines
for Error and Exception Handling for the explanation. Note that, consistently
with this, the documentation of the member functions doesn't use the term
"precondition" for conditions that cause an exception to be emitted (the C++
standard uses the term "requires" in such cases).
== Acknowledgments
We would like to thank the Boost community for putting in the time to review and
accept this library. This library is much better than it ever would have been
due to all the suggestions from Boost members. We especially thank Matt Marcus
for taking on the task of review manager. Also, a special thanks goes to James
Kanze for his invaluable help with the internationalization issues.

26
doc/mrdocs.yml Normal file
View File

@@ -0,0 +1,26 @@
# ============================================================================
# Copyright 2025 Gennaro Prota.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# ============================================================================
verbose: true
source-root: ..
cmake: '-DDYNAMIC_BITSET_MRDOCS_BUILD=ON'
input:
- ../include
exclude-symbols:
- 'boost::detail'
- 'boost::detail::**'
- 'boost::to_string_helper'
- 'boost::dynamic_bitset::bit_appender'
- 'std'
- 'std::**'
# Why does MrDocs pick up ::size_t?
- 'size_t'
file-patterns:
- '*.hpp'
multipage: false
generator: adoc

2366
doc/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

21
doc/package.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "doc",
"version": "1.0.0",
"description": "The documentation for the dynamic_bitset library is the top-level index.html file.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@alandefreitas/antora-cpp-reference-extension": "^0.0.3",
"@antora/lunr-extension": "^1.0.0-alpha.10",
"@asciidoctor/tabs": "^1.0.0-beta.6",
"@cppalliance/antora-cpp-reference-extension": "^0.0.6",
"@cppalliance/antora-cpp-tagfiles-extension": "^0.0.4",
"@cppalliance/asciidoctor-boost-links": "^0.0.2",
"antora": "^3.1.10"
}
}

View File

@@ -1 +1 @@
The documentation for the dynamic_bitset library is the top-level index.html file.
To build the documentation, run build_docs.sh.

File diff suppressed because it is too large Load Diff

View File

@@ -7,9 +7,7 @@
#
# -----------------------------------------------------------
exe timing_tests
: timing_tests.cpp
;
project : requirements <library>/boost/dynamic_bitset//boost_dynamic_bitset ;
exe example1
: example1.cpp

View File

@@ -3,8 +3,6 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// An example of setting and reading some bits. Note that operator[]
// goes from the least-significant bit at 0 to the most significant
// bit at size()-1. The operator<< for dynamic_bitset prints the
@@ -17,17 +15,18 @@
// 10011
// ---------------------------------------------------------------------
#include "boost/dynamic_bitset.hpp"
#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main()
int
main()
{
boost::dynamic_bitset<> x(5); // all 0's by default
x[0] = 1;
x[1] = 1;
x[4] = 1;
for (boost::dynamic_bitset<>::size_type i = 0; i < x.size(); ++i)
std::cout << x[i];
boost::dynamic_bitset<> x( 5 ); // all 0's by default
x[ 0 ] = 1;
x[ 1 ] = 1;
x[ 4 ] = 1;
for ( boost::dynamic_bitset<>::size_type i = 0; i < x.size(); ++i )
std::cout << x[ i ];
std::cout << "\n";
std::cout << x << "\n";

View File

@@ -10,23 +10,23 @@
// bits(2) = 10
// bits(3) = 11
#include "boost/dynamic_bitset.hpp"
#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main()
int
main()
{
const boost::dynamic_bitset<> b0(2, 0ul);
std::cout << "bits(0) = " << b0 << std::endl;
const boost::dynamic_bitset<> b0( 2, 0ul );
std::cout << "bits(0) = " << b0 << std::endl;
const boost::dynamic_bitset<> b1(2, 1ul);
std::cout << "bits(1) = " << b1 << std::endl;
const boost::dynamic_bitset<> b1( 2, 1ul );
std::cout << "bits(1) = " << b1 << std::endl;
const boost::dynamic_bitset<> b2(2, 2ul);
std::cout << "bits(2) = " << b2 << std::endl;
const boost::dynamic_bitset<> b2( 2, 2ul );
std::cout << "bits(2) = " << b2 << std::endl;
const boost::dynamic_bitset<> b3(2, 3ul);
std::cout << "bits(3) = " << b3 << std::endl;
const boost::dynamic_bitset<> b3( 2, 3ul );
std::cout << "bits(3) = " << b3 << std::endl;
return 0;
return 0;
}

View File

@@ -19,38 +19,36 @@
// Shifted left by 1: 001000100
// Shifted right by 1: 010010001
#include "boost/dynamic_bitset.hpp"
#include <ostream>
#include <iostream>
#include <ostream>
int main()
int
main()
{
boost::dynamic_bitset<> mask(12, 2730ul);
boost::dynamic_bitset<> mask( 12, 2730ul );
std::cout << "mask = " << mask << std::endl;
boost::dynamic_bitset<> x;
std::cout << "x.size() = " << x.size() << std::endl;
std::cout << "Enter a bitset in binary: x = " << std::flush;
if (std::cin >> x) {
if ( std::cin >> x ) {
const std::size_t sz = x.size();
std::cout << std::endl;
std::cout << "Input number: " << x << std::endl;
std::cout << "x.size() is now: " << sz << std::endl;
bool fits_in_ulong = true;
unsigned long ul = 0;
bool fits_in_ulong = true;
unsigned long ul = 0;
try {
ul = x.to_ulong();
} catch(std::overflow_error &) {
} catch ( std::overflow_error & ) {
fits_in_ulong = false;
}
std::cout << "As unsigned long: ";
if(fits_in_ulong) {
if ( fits_in_ulong ) {
std::cout << ul;
} else {
std::cout << "(overflow exception)";
@@ -58,14 +56,14 @@ int main()
std::cout << std::endl;
mask.resize(sz);
mask.resize( sz );
std::cout << "Mask (possibly resized): " << mask << std::endl;
std::cout << "And with mask: " << (x & mask) << std::endl;
std::cout << "Or with mask: " << (x | mask) << std::endl;
std::cout << "Shifted left by 1: " << (x << 1) << std::endl;
std::cout << "Shifted right by 1: " << (x >> 1) << std::endl;
std::cout << "And with mask: " << ( x & mask ) << std::endl;
std::cout << "Or with mask: " << ( x | mask ) << std::endl;
std::cout << "Shifted left by 1: " << ( x << 1 ) << std::endl;
std::cout << "Shifted right by 1: " << ( x >> 1 ) << std::endl;
}
return 0;
}

View File

@@ -1,142 +0,0 @@
// -----------------------------------------------------------
//
// Copyright (c) 2003-2004 Gennaro Prota
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// -----------------------------------------------------------
// boost::dynamic_bitset timing tests
//
// NOTE:
// ~~~~~
// This is a preliminary, incomplete version.
//
// If you are interested in having more benchmarks please make a
// request on the boost list, which could encourage me to continue
// this work.
// Also, if you use boost::dynamic_bitset on a platform where
// CHAR_BIT >= 9 I suggest experimenting with the size of the count
// table in detail/dynamic_bitset.hpp and report any interesting
// discovery on the list as well.
// You might also want to try both counting methods (by_bytes vs.
// by_blocks) to see if the one that is selected automatically is
// actually the fastest on your system.
//
//
// -----------------------------------------------------------------------//
#include "boost/config.hpp"
#if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS)
// for pre 3.0 versions of libstdc++
# define BOOST_OLD_IOSTREAMS
#endif
// ------------------------------------------------- //
#include <typeinfo>
#include <iostream>
#if !defined(BOOST_OLD_IOSTREAMS)
# include <ostream>
#endif
#include "boost/cstdlib.hpp"
#include "boost/version.hpp"
#include "boost/timer.hpp"
#include "boost/dynamic_bitset.hpp"
namespace {
// the m_ prefixes, below, are mainly to avoid problems with g++:
// see http://gcc.gnu.org/ml/gcc-bugs/1999-03n/msg00884.html
//
class boost_version {
int m_major;
int m_minor;
int m_subminor;
public:
boost_version(unsigned long v = BOOST_VERSION):
m_major(v / 100000), m_minor(v / 100 % 1000), m_subminor(v % 100) {}
friend std::ostream & operator<<(std::ostream &, const boost_version &);
};
// give up using basic_ostream, to avoid headaches with old libraries
std::ostream& operator<<(std::ostream& os, const boost_version & v) {
return os << v.m_major << '.' << v.m_minor << '.' << v.m_subminor;
}
}
void prologue()
{
std::cout << '\n';
std::cout << "Compiler: " << BOOST_COMPILER << '\n';
std::cout << "Std lib : " << BOOST_STDLIB << '\n';
std::cout << "Boost v.: " << boost_version() << '\n';
std::cout << '\n';
}
template <typename T>
void timing_test(T* = 0) // dummy parameter to workaround VC6
{
const unsigned long num = 30 * 100000;
// This variable is printed at the end of the test,
// to prevent the optimizer from removing the call to
// count() in the loop below.
typename boost::dynamic_bitset<T>::size_type dummy = 0;
std::cout << "\nTimings for dynamic_bitset<" << typeid(T).name()
<< "> [" << num << " iterations]\n";
std::cout << "--------------------------------------------------\n";
{
boost::timer time;
const typename boost::dynamic_bitset<T>::size_type sz = 5000;
for (unsigned long i = 0; i < num; ++i) {
boost::dynamic_bitset<T> bs(sz, i);
dummy += bs.count();
}
const double elaps = time.elapsed();
std::cout << "Elapsed: " << elaps << '\n';
}
std::cout << "(total count: " << dummy << ")\n\n";
}
int main()
{
prologue();
timing_test<unsigned char>();
timing_test<unsigned short>();
timing_test<unsigned int>();
timing_test<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
timing_test< ::boost::ulong_long_type>();
# endif
return boost::exit_success;
}

View File

@@ -1,241 +0,0 @@
// -----------------------------------------------------------
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
//
// Copyright (c) 2014 Glen Joseph Fernandes
// glenfe at live dot com
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// -----------------------------------------------------------
#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
#include <memory>
#include <cstddef>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
namespace boost {
namespace detail {
namespace dynamic_bitset_impl {
// Gives (read-)access to the object representation
// of an object of type T (3.9p4). CANNOT be used
// on a base sub-object
//
template <typename T>
inline const unsigned char * object_representation (T* p)
{
return static_cast<const unsigned char *>(static_cast<const void *>(p));
}
template<typename T, int amount, int width /* = default */>
struct shifter
{
static void left_shift(T & v) {
amount >= width ? (v = 0)
: (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount));
}
};
// ------- count function implementation --------------
typedef unsigned char byte_type;
// These two entities
//
// enum mode { access_by_bytes, access_by_blocks };
// template <mode> struct mode_to_type {};
//
// were removed, since the regression logs (as of 24 Aug 2008)
// showed that several compilers had troubles with recognizing
//
// const mode m = access_by_bytes
//
// as a constant expression
//
// * So, we'll use bool, instead of enum *.
//
template <bool value>
struct value_to_type
{
value_to_type() {}
};
const bool access_by_bytes = true;
const bool access_by_blocks = false;
// the table: wrapped in a class template, so
// that it is only instantiated if/when needed
//
template <bool dummy_name = true>
struct count_table { static const byte_type table[]; };
template <>
struct count_table<false> { /* no table */ };
const unsigned int table_width = 8;
template <bool b>
const byte_type count_table<b>::table[] =
{
// Automatically generated by GPTableGen.exe v.1.0
//
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,
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,
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,
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,
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,
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,
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,
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
};
// overload for access by bytes
//
template <typename Iterator>
inline std::size_t do_count(Iterator first, std::size_t length,
int /*dummy param*/,
value_to_type<access_by_bytes>* )
{
std::size_t num = 0;
if (length)
{
const byte_type * p = object_representation(&*first);
length *= sizeof(*first);
do {
num += count_table<>::table[*p];
++p;
--length;
} while (length);
}
return num;
}
// overload for access by blocks
//
template <typename Iterator, typename ValueType>
inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
value_to_type<access_by_blocks>*)
{
std::size_t num = 0;
while (length){
ValueType value = *first;
while (value) {
num += count_table<>::table[value & ((1u<<table_width) - 1)];
value >>= table_width;
}
++first;
--length;
}
return num;
}
// -------------------------------------------------------
// Some library implementations simply return a dummy
// value such as
//
// size_type(-1) / sizeof(T)
//
// from vector<>::max_size. This tries to get more
// meaningful info.
//
template <typename T>
inline typename T::size_type vector_max_size_workaround(const T & v)
BOOST_NOEXCEPT
{
typedef typename T::allocator_type allocator_type;
const allocator_type& alloc = v.get_allocator();
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef std::allocator_traits<allocator_type> allocator_traits;
const typename allocator_traits::size_type alloc_max =
allocator_traits::max_size(alloc);
#else
const typename allocator_type::size_type alloc_max = alloc.max_size();
#endif
const typename T::size_type container_max = v.max_size();
return alloc_max < container_max ? alloc_max : container_max;
}
// for static_asserts
template <typename T>
struct allowed_block_type {
enum { value = T(-1) > 0 }; // ensure T has no sign
};
template <>
struct allowed_block_type<bool> {
enum { value = false };
};
template <typename T>
struct is_numeric {
enum { value = false };
};
# define BOOST_dynamic_bitset_is_numeric(x) \
template<> \
struct is_numeric< x > { \
enum { value = true }; \
} /**/
BOOST_dynamic_bitset_is_numeric(bool);
BOOST_dynamic_bitset_is_numeric(char);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_dynamic_bitset_is_numeric(wchar_t);
#endif
BOOST_dynamic_bitset_is_numeric(signed char);
BOOST_dynamic_bitset_is_numeric(short int);
BOOST_dynamic_bitset_is_numeric(int);
BOOST_dynamic_bitset_is_numeric(long int);
BOOST_dynamic_bitset_is_numeric(unsigned char);
BOOST_dynamic_bitset_is_numeric(unsigned short);
BOOST_dynamic_bitset_is_numeric(unsigned int);
BOOST_dynamic_bitset_is_numeric(unsigned long);
#if defined(BOOST_HAS_LONG_LONG)
BOOST_dynamic_bitset_is_numeric(::boost::long_long_type);
BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type);
#endif
// intentionally omitted
//BOOST_dynamic_bitset_is_numeric(float);
//BOOST_dynamic_bitset_is_numeric(double);
//BOOST_dynamic_bitset_is_numeric(long double);
#undef BOOST_dynamic_bitset_is_numeric
} // dynamic_bitset_impl
} // namespace detail
} // namespace boost
#endif // include guard

View File

@@ -13,38 +13,25 @@
#define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
// support for pre 3.0 libstdc++ - thanks Phil Edwards!
#if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS)
# define BOOST_OLD_IOSTREAMS
#endif
// no-op function to workaround gcc bug c++/8419
//
namespace boost { namespace detail {
template <typename T> T make_non_const(T t) { return t; }
}}
namespace boost {
namespace detail {
template< typename T >
T
make_non_const( T t )
{
return t;
}
}
}
#if defined(__GNUC__)
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) \
(boost::detail::make_non_const(expr))
#if defined( __GNUC__ )
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT( expr ) \
( boost::detail::make_non_const( expr ) )
#else
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) (expr)
#endif
//
#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \
|| (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
#endif
// if we can't use friends then we simply expose private members
//
#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_PRIVATE public
#else
#define BOOST_DYNAMIC_BITSET_PRIVATE private
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT( expr ) ( expr )
#endif
// A couple of macros to cope with libraries without locale
@@ -54,18 +41,18 @@ namespace boost { namespace detail {
// the first macro is a no-op and the second one just expands
// to its parameter c.
//
#if defined (BOOST_USE_FACET)
#if defined BOOST_USE_FACET
#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) \
const std::ctype<ch> & name = \
BOOST_USE_FACET(std::ctype<ch>, loc) /**/
# define BOOST_DYNAMIC_BITSET_CTYPE_FACET( ch, name, loc ) \
const std::ctype< ch > & name = \
BOOST_USE_FACET( std::ctype< ch >, loc ) /**/
#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) \
(fac.widen(c))
# define BOOST_DYNAMIC_BITSET_WIDEN_CHAR( fac, c ) \
( fac.widen( c ) )
#else
#define BOOST_DYNAMIC_BITSET_CTYPE_FACET(ch, name, loc) /**/
#define BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, c) c
# define BOOST_DYNAMIC_BITSET_CTYPE_FACET( ch, name, loc ) /**/
# define BOOST_DYNAMIC_BITSET_WIDEN_CHAR( fac, c ) c
#endif

View File

@@ -0,0 +1,141 @@
// -----------------------------------------------------------
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Glen Joseph Fernandes
// (glenjofe@gmail.com)
// Copyright (c) 2018 Evgeny Shulgin
// Copyright (c) 2019 Andrey Semashev
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// -----------------------------------------------------------
#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
#include "boost/config.hpp"
#include "boost/core/allocator_access.hpp"
#include <cstddef>
#include <memory>
namespace boost {
namespace detail {
namespace dynamic_bitset_impl {
template< typename T, int amount, int width /* = default */ >
struct shifter
{
static void
left_shift( T & v )
{
amount >= width ? ( v = 0 )
: ( v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT( amount ) );
}
};
template< bool value >
struct value_to_type
{
};
// Some library implementations simply return a dummy
// value such as
//
// size_type(-1) / sizeof(T)
//
// from vector<>::max_size. This tries to get more
// meaningful info.
//
template< typename T >
inline typename T::size_type
vector_max_size_workaround( const T & v )
BOOST_NOEXCEPT
{
typedef typename T::allocator_type allocator_type;
const allocator_type & alloc = v.get_allocator();
typename boost::allocator_size_type< allocator_type >::type alloc_max =
boost::allocator_max_size( alloc );
const typename T::size_type container_max = v.max_size();
return alloc_max < container_max ? alloc_max : container_max;
}
// for static_asserts
template< typename T >
struct allowed_block_type
{
enum
{
value = T( -1 ) > 0 // ensure T has no sign
};
};
template<>
struct allowed_block_type< bool >
{
enum
{
value = false
};
};
template< typename T >
struct is_numeric
{
enum
{
value = false
};
};
#define BOOST_dynamic_bitset_is_numeric( x ) \
template<> \
struct is_numeric< x > \
{ \
enum \
{ \
value = true \
}; \
} /**/
BOOST_dynamic_bitset_is_numeric( bool );
BOOST_dynamic_bitset_is_numeric( char );
#if ! defined( BOOST_NO_INTRINSIC_WCHAR_T )
BOOST_dynamic_bitset_is_numeric( wchar_t );
#endif
BOOST_dynamic_bitset_is_numeric( signed char );
BOOST_dynamic_bitset_is_numeric( short int );
BOOST_dynamic_bitset_is_numeric( int );
BOOST_dynamic_bitset_is_numeric( long int );
BOOST_dynamic_bitset_is_numeric( unsigned char );
BOOST_dynamic_bitset_is_numeric( unsigned short );
BOOST_dynamic_bitset_is_numeric( unsigned int );
BOOST_dynamic_bitset_is_numeric( unsigned long );
#if defined( BOOST_HAS_LONG_LONG )
BOOST_dynamic_bitset_is_numeric( ::boost::long_long_type );
BOOST_dynamic_bitset_is_numeric( ::boost::ulong_long_type );
#endif
// intentionally omitted
// BOOST_dynamic_bitset_is_numeric(float);
// BOOST_dynamic_bitset_is_numeric(double);
// BOOST_dynamic_bitset_is_numeric(long double);
#undef BOOST_dynamic_bitset_is_numeric
} // dynamic_bitset_impl
} // namespace detail
} // namespace boost
#endif // include guard

View File

@@ -1,7 +1,7 @@
// -----------------------------------------------------------
// lowest_bit.hpp
// lowest_bit()
//
// Position of the lowest bit 'on'
// Position of the lowest bit that is set.
//
// Copyright (c) 2003-2004, 2008 Gennaro Prota
//
@@ -14,26 +14,25 @@
#ifndef BOOST_LOWEST_BIT_HPP_GP_20030301
#define BOOST_LOWEST_BIT_HPP_GP_20030301
#include <assert.h>
#include "boost/assert.hpp"
#include "boost/integer/integer_log2.hpp"
namespace boost {
namespace detail {
template <typename T>
int lowest_bit(T x) {
assert(x >= 1); // PRE
// clear all bits on except the rightmost one,
// then calculate the logarithm base 2
//
return boost::integer_log2<T>( x - ( x & (x-1) ) );
}
template< typename T >
int
lowest_bit( T x )
{
BOOST_ASSERT( x >= 1 );
// Clear all the bits that are set except the rightmost one,
// then calculate the logarithm to base 2.
//
return boost::integer_log2< T >( x - ( x & ( x - 1 ) ) );
}
}
}
#endif // include guard

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -11,36 +11,39 @@
#ifndef BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP
#define BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP
#include "boost/core/nvp.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include <boost/serialization/vector.hpp>
namespace boost {
// implementation for optional zero-copy serialization support
template <typename Block, typename Allocator>
class dynamic_bitset<Block, Allocator>::serialize_impl
{
public:
template <typename Ar>
static void serialize(Ar& ar, dynamic_bitset<Block, Allocator>& bs, unsigned) {
ar & serialization::make_nvp("m_num_bits", bs.m_num_bits)
& serialization::make_nvp("m_bits", bs.m_bits);
}
};
// implementation for optional zero-copy serialization support
template< typename Block, typename Allocator >
class dynamic_bitset< Block, Allocator >::serialize_impl
{
public:
template< typename Ar >
static void
serialize( Ar & ar, dynamic_bitset< Block, Allocator > & bs, unsigned )
{
ar & boost::make_nvp( "m_num_bits", bs.m_num_bits )
& boost::make_nvp( "m_bits", bs.m_bits );
}
};
}
// ADL hook to Boost Serialization library
namespace boost {
namespace serialization {
namespace serialization {
template <typename Ar, typename Block, typename Allocator>
void serialize(Ar& ar, dynamic_bitset<Block, Allocator>& bs, unsigned version) {
dynamic_bitset<Block, Allocator>::serialize_impl::serialize(ar, bs, version);
}
template< typename Ar, typename Block, typename Allocator >
void
serialize( Ar & ar, dynamic_bitset< Block, Allocator > & bs, unsigned version )
{
dynamic_bitset< Block, Allocator >::serialize_impl::serialize( ar, bs, version );
}
} // namespace serialization
} // namespace serialization
} // namespace boost
#endif // include guard

View File

@@ -16,8 +16,7 @@
namespace boost {
template <typename Block = unsigned long,
typename Allocator = std::allocator<Block> >
template< typename Block = unsigned long, typename Allocator = std::allocator< Block > >
class dynamic_bitset;
}

View File

@@ -8,8 +8,8 @@
Automatic redirection failed, please go to
<a href="dynamic_bitset.html">dynamic_bitset.html</a>.&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@@ -5,12 +5,13 @@
"Jeremy Siek",
"Chuck Allison"
],
"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.",
"description": "The dynamic_bitset template represents a set of bits. It provides access to the value of individual bits via 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 can change at runtime.",
"documentation": "dynamic_bitset.html",
"category": [
"Containers"
"Data structures"
],
"maintainers": [
"Jeremy Siek <jeremy.siek -at- gmail.com>"
]
"Gennaro Prota <firstName.lastName -at- gmail.com>"
],
"cxxstd": "11"
}

View File

@@ -4,13 +4,47 @@
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
import os ;
import testing ;
# import rules for testing conditional on config file variables
import-search /boost/config/checks ;
import config : requires ;
project : requirements <library>/boost/dynamic_bitset//boost_dynamic_bitset ;
test-suite dynamic_bitset :
[ run dyn_bitset_unit_tests1.cpp ]
[ run dyn_bitset_unit_tests2.cpp ]
[ run dyn_bitset_unit_tests3.cpp ]
[ run dyn_bitset_unit_tests4.cpp ]
[ run dyn_bitset_unit_tests5.cpp /boost/serialization//boost_serialization
: : : <define>_SCL_SECURE_NO_WARNINGS=1 ]
[ run dyn_bitset_unit_tests1.cpp : : : <library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system ]
[ run dyn_bitset_unit_tests2.cpp : : : <library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system ]
[ run dyn_bitset_unit_tests3.cpp : : : <library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system ]
[ run dyn_bitset_unit_tests4.cpp : : : <library>/boost/filesystem//boost_filesystem
<library>/boost/system//boost_system ]
[ run test_ambiguous_set.cpp ]
[ run test_lowest_bit.cpp ]
[ run test_boost_hash.cpp ]
[ run test_std_hash.cpp : : : [ requires cxx11_hdr_unordered_set ] ]
[ compile-fail test_std_hash.cpp : [ requires cxx11_hdr_unordered_set ]
<define>BOOST_DYNAMIC_BITSET_NO_STD_HASH
: test_std_hash_disabled ]
;
# due to https://github.com/boostorg/serialization/issues/108
if ! [ os.environ UBSAN_OPTIONS ]
{
test-suite dynamic_bitset_serialization :
[ run dyn_bitset_unit_tests5.cpp
: : : <define>_SCL_SECURE_NO_WARNINGS=1
<library>/boost/filesystem//boost_filesystem
<library>/boost/serialization//boost_serialization
<library>/boost/system//boost_system ]
;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
# Copyright 2021-2024 Alexander Grund
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_subdir_test LANGUAGES CXX)
# Those 2 should work the same
# while using find_package for the installed Boost avoids the need to manually specify dependencies
if(BOOST_CI_INSTALL_TEST)
find_package(boost_dynamic_bitset REQUIRED)
else()
set(BOOST_INCLUDE_LIBRARIES dynamic_bitset)
add_subdirectory(../../../.. deps/boost EXCLUDE_FROM_ALL)
endif()
add_executable(main main.cpp)
target_link_libraries(main Boost::dynamic_bitset)
enable_testing()
add_test(NAME main COMMAND main)

8
test/cmake_test/main.cpp Normal file
View File

@@ -0,0 +1,8 @@
#include <boost/dynamic_bitset.hpp>
int main()
{
const boost::dynamic_bitset<> db{3, 4};
return db[2] ? 0 : 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
// Copyright (c) 2018 Evgeny Shulgin
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,285 +11,368 @@
// -----------------------------------------------------------
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/config.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
template< typename Block >
void
run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test< bitset_type > Tests;
const int bits_per_block = bitset_type::bits_per_block;
typedef boost::dynamic_bitset< Block > bitset_type;
typedef bitset_test< bitset_type > Tests;
const int bits_per_block = bitset_type::bits_per_block;
std::string long_string = get_long_string();
std::string long_string = get_long_string();
//=====================================================================
// Test operator&=
{
boost::dynamic_bitset<Block> lhs, rhs;
Tests::and_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("1")), rhs(std::string("0"));
Tests::and_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string.size(), 0), rhs(long_string);
Tests::and_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string.size(), 1), rhs(long_string);
Tests::and_assignment(lhs, rhs);
}
//=====================================================================
// Test operator |=
{
boost::dynamic_bitset<Block> lhs, rhs;
Tests::or_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("1")), rhs(std::string("0"));
Tests::or_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string.size(), 0), rhs(long_string);
Tests::or_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string.size(), 1), rhs(long_string);
Tests::or_assignment(lhs, rhs);
}
//=====================================================================
// Test operator^=
{
boost::dynamic_bitset<Block> lhs, rhs;
Tests::xor_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("1")), rhs(std::string("0"));
Tests::xor_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("0")), rhs(std::string("1"));
Tests::xor_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string), rhs(long_string);
Tests::xor_assignment(lhs, rhs);
}
//=====================================================================
// Test operator-=
{
boost::dynamic_bitset<Block> lhs, rhs;
Tests::sub_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("1")), rhs(std::string("0"));
Tests::sub_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(std::string("0")), rhs(std::string("1"));
Tests::sub_assignment(lhs, rhs);
}
{
boost::dynamic_bitset<Block> lhs(long_string), rhs(long_string);
Tests::sub_assignment(lhs, rhs);
}
//=====================================================================
// Test operator<<=
{ // case pos == 0
std::size_t pos = 0;
//=====================================================================
// Test operator&=
{
boost::dynamic_bitset<Block> b;
Tests::shift_left_assignment(b, pos);
boost::dynamic_bitset< Block > lhs, rhs;
Tests::and_assignment( lhs, rhs );
}
{
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_left_assignment(b, pos);
boost::dynamic_bitset< Block > lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::and_assignment( lhs, rhs );
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_left_assignment(b, pos);
boost::dynamic_bitset< Block > lhs( long_string.size(), 0 ), rhs( long_string );
Tests::and_assignment( lhs, rhs );
}
}
{
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for (int i = 1; i <= how_many; ++i) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset<Block> b(long_string);
{
boost::dynamic_bitset< Block > lhs( long_string.size(), 1 ), rhs( long_string );
Tests::and_assignment( lhs, rhs );
}
//=====================================================================
// Test operator |=
{
boost::dynamic_bitset< Block > lhs, rhs;
Tests::or_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::or_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( long_string.size(), 0 ), rhs( long_string );
Tests::or_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( long_string.size(), 1 ), rhs( long_string );
Tests::or_assignment( lhs, rhs );
}
//=====================================================================
// Test operator^=
{
boost::dynamic_bitset< Block > lhs, rhs;
Tests::xor_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::xor_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( std::string( "0" ) ), rhs( std::string( "1" ) );
Tests::xor_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( long_string ), rhs( long_string );
Tests::xor_assignment( lhs, rhs );
}
//=====================================================================
// Test operator-=
{
boost::dynamic_bitset< Block > lhs, rhs;
Tests::sub_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::sub_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( std::string( "0" ) ), rhs( std::string( "1" ) );
Tests::sub_assignment( lhs, rhs );
}
{
boost::dynamic_bitset< Block > lhs( long_string ), rhs( long_string );
Tests::sub_assignment( lhs, rhs );
}
//=====================================================================
// Test operator<<=
{ // case pos == 0
std::size_t pos = 0;
{
boost::dynamic_bitset< Block > b;
Tests::shift_left_assignment( b, pos );
}
{
boost::dynamic_bitset< Block > b( std::string( "1010" ) );
Tests::shift_left_assignment( b, pos );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_left_assignment( b, pos );
}
}
{
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for ( int i = 1; i <= how_many; ++i ) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_left_assignment(b, multiple);
Tests::shift_left_assignment(b, non_multiple);
Tests::shift_left_assignment( b, multiple );
Tests::shift_left_assignment( b, non_multiple );
}
}
}
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_left_assignment(b, pos);
}
{ // case pos >= n
std::size_t pos = long_string.size();
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_left_assignment(b, pos);
}
//=====================================================================
// Test operator>>=
{ // case pos == 0
std::size_t pos = 0;
{
boost::dynamic_bitset<Block> b;
Tests::shift_right_assignment(b, pos);
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_left_assignment( b, pos );
}
{ // case pos >= n
std::size_t pos = long_string.size();
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_left_assignment( b, pos );
}
//=====================================================================
// Test operator>>=
{ // case pos == 0
std::size_t pos = 0;
{
boost::dynamic_bitset< Block > b;
Tests::shift_right_assignment( b, pos );
}
{
boost::dynamic_bitset< Block > b( std::string( "1010" ) );
Tests::shift_right_assignment( b, pos );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_right_assignment( b, pos );
}
}
{
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_right_assignment(b, pos);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_right_assignment(b, pos);
}
}
{
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for (int i = 1; i <= how_many; ++i) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset<Block> b(long_string);
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for ( int i = 1; i <= how_many; ++i ) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_right_assignment(b, multiple);
Tests::shift_right_assignment(b, non_multiple);
Tests::shift_right_assignment( b, multiple );
Tests::shift_right_assignment( b, non_multiple );
}
}
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_right_assignment( b, pos );
}
{ // case pos >= n
std::size_t pos = long_string.size();
boost::dynamic_bitset< Block > b( long_string );
Tests::shift_right_assignment( b, pos );
}
//=====================================================================
// test b.set()
{
boost::dynamic_bitset< Block > b;
Tests::set_all( b );
}
{
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::set_all( b );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::set_all( b );
}
//=====================================================================
// Test b.set(pos)
{ // case pos >= b.size()
boost::dynamic_bitset< Block > b;
Tests::set_one( b, 0, true );
Tests::set_one( b, 0, false );
}
{ // case pos < b.size()
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::set_one( b, 0, true );
Tests::set_one( b, 0, false );
}
{ // case pos == b.size() / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::set_one( b, long_string.size() / 2, true );
Tests::set_one( b, long_string.size() / 2, false );
}
//=====================================================================
// Test b.set(pos, len)
{ // case size is 1
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::set_segment( b, 0, 1, true );
Tests::set_segment( b, 0, 1, false );
}
{ // case fill the whole set
boost::dynamic_bitset< Block > b( long_string );
Tests::set_segment( b, 0, b.size(), true );
Tests::set_segment( b, 0, b.size(), false );
}
{ // case pos = size / 4, len = size / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::set_segment( b, b.size() / 4, b.size() / 2, true );
Tests::set_segment( b, b.size() / 4, b.size() / 2, false );
}
{ // case pos = block_size / 2, len = size - block_size
boost::dynamic_bitset< Block > b( long_string );
Tests::set_segment( b, boost::dynamic_bitset< Block >::bits_per_block / 2, b.size() - boost::dynamic_bitset< Block >::bits_per_block, true );
Tests::set_segment( b, boost::dynamic_bitset< Block >::bits_per_block / 2, b.size() - boost::dynamic_bitset< Block >::bits_per_block, false );
}
{ // case pos = 1, len = size - 2
boost::dynamic_bitset< Block > b( long_string );
Tests::set_segment( b, 1, b.size() - 2, true );
Tests::set_segment( b, 1, b.size() - 2, false );
}
{ // case pos = 3, len = 7
boost::dynamic_bitset< Block > b( long_string );
Tests::set_segment( b, 3, 7, true );
Tests::set_segment( b, 3, 7, false );
}
//=====================================================================
// Test b.reset()
{
boost::dynamic_bitset< Block > b;
Tests::reset_all( b );
}
{
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::reset_all( b );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_all( b );
}
//=====================================================================
// Test b.reset(pos)
{ // case pos >= b.size()
boost::dynamic_bitset< Block > b;
Tests::reset_one( b, 0 );
}
{ // case pos < b.size()
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::reset_one( b, 0 );
}
{ // case pos == b.size() / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_one( b, long_string.size() / 2 );
}
//=====================================================================
// Test b.reset(pos, len)
{ // case size is 1
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::reset_segment( b, 0, 1 );
}
{ // case fill the whole set
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_segment( b, 0, b.size() );
}
{ // case pos = size / 4, len = size / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_segment( b, b.size() / 4, b.size() / 2 );
}
{ // case pos = block_size / 2, len = size - block_size
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_segment( b, boost::dynamic_bitset< Block >::bits_per_block / 2, b.size() - boost::dynamic_bitset< Block >::bits_per_block );
}
{ // case pos = 1, len = size - 2
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_segment( b, 1, b.size() - 2 );
}
{ // case pos = 3, len = 7
boost::dynamic_bitset< Block > b( long_string );
Tests::reset_segment( b, 3, 7 );
}
//=====================================================================
// Test ~b
{
boost::dynamic_bitset< Block > b;
Tests::operator_flip( b );
}
{
boost::dynamic_bitset< Block > b( std::string( "1" ) );
Tests::operator_flip( b );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::operator_flip( b );
}
//=====================================================================
// Test b.flip()
{
boost::dynamic_bitset< Block > b;
Tests::flip_all( b );
}
{
boost::dynamic_bitset< Block > b( std::string( "1" ) );
Tests::flip_all( b );
}
{
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_all( b );
}
//=====================================================================
// Test b.flip(pos)
{ // case pos >= b.size()
boost::dynamic_bitset< Block > b;
Tests::flip_one( b, 0 );
}
{ // case pos < b.size()
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::flip_one( b, 0 );
}
{ // case pos == b.size() / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_one( b, long_string.size() / 2 );
}
//=====================================================================
// Test b.flip(pos, len)
{ // case size is 1
boost::dynamic_bitset< Block > b( std::string( "0" ) );
Tests::flip_segment( b, 0, 1 );
}
{ // case fill the whole set
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_segment( b, 0, b.size() );
}
{ // case pos = size / 4, len = size / 2
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_segment( b, b.size() / 4, b.size() / 2 );
}
{ // case pos = block_size / 2, len = size - block_size
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_segment( b, boost::dynamic_bitset< Block >::bits_per_block / 2, b.size() - boost::dynamic_bitset< Block >::bits_per_block );
}
{ // case pos = 1, len = size - 2
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_segment( b, 1, b.size() - 2 );
}
{ // case pos = 3, len = 7
boost::dynamic_bitset< Block > b( long_string );
Tests::flip_segment( b, 3, 7 );
}
}
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_right_assignment(b, pos);
}
{ // case pos >= n
std::size_t pos = long_string.size();
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_right_assignment(b, pos);
}
//=====================================================================
// test b.set()
{
boost::dynamic_bitset<Block> b;
Tests::set_all(b);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::set_all(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::set_all(b);
}
//=====================================================================
// Test b.set(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::set_one(b, 0, true);
Tests::set_one(b, 0, false);
}
{ // case pos < b.size()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::set_one(b, 0, true);
Tests::set_one(b, 0, false);
}
{ // case pos == b.size() / 2
boost::dynamic_bitset<Block> b(long_string);
Tests::set_one(b, long_string.size()/2, true);
Tests::set_one(b, long_string.size()/2, false);
}
//=====================================================================
// Test b.reset()
{
boost::dynamic_bitset<Block> b;
Tests::reset_all(b);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::reset_all(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::reset_all(b);
}
//=====================================================================
// Test b.reset(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::reset_one(b, 0);
}
{ // case pos < b.size()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::reset_one(b, 0);
}
{ // case pos == b.size() / 2
boost::dynamic_bitset<Block> b(long_string);
Tests::reset_one(b, long_string.size()/2);
}
//=====================================================================
// Test ~b
{
boost::dynamic_bitset<Block> b;
Tests::operator_flip(b);
}
{
boost::dynamic_bitset<Block> b(std::string("1"));
Tests::operator_flip(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::operator_flip(b);
}
//=====================================================================
// Test b.flip()
{
boost::dynamic_bitset<Block> b;
Tests::flip_all(b);
}
{
boost::dynamic_bitset<Block> b(std::string("1"));
Tests::flip_all(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::flip_all(b);
}
//=====================================================================
// Test b.flip(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::flip_one(b, 0);
}
{ // case pos < b.size()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::flip_one(b, 0);
}
{ // case pos == b.size() / 2
boost::dynamic_bitset<Block> b(long_string);
Tests::flip_one(b, long_string.size()/2);
}
}
int
test_main(int, char*[])
main()
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
run_test_cases< unsigned char >();
run_test_cases< unsigned short >();
run_test_cases< unsigned int >();
run_test_cases< unsigned long >();
#ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type >();
#endif
return 0;
return boost::report_errors();
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,328 +8,304 @@
//
// -----------------------------------------------------------
#include <fstream>
#include <string>
#include <cstddef> // for std::size_t
#include <stdexcept> // for std::logic_error
#include <assert.h>
#include "boost/config.hpp"
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#endif
#include "bitset_test.hpp"
#include "boost/config.hpp"
#include "boost/config/workaround.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/detail/workaround.hpp"
#include <assert.h>
#include <cstddef>
#include <fstream>
#include <stdexcept>
#include <string>
// Codewarrior 8.3 for Win fails without this.
// Thanks Howard Hinnant ;)
#if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
# pragma parse_func_templ off
#if ! defined( BOOST_NO_STRINGSTREAM )
# include <sstream>
#endif
#if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
# define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
# define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
#endif
#if !defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
std::wstring widen_string( const std::string & str,
const std::locale & loc = std::locale() )
#if ! defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
std::wstring
widen_string( const std::string & str, const std::locale & loc = std::locale() )
{
std::wstring result;
const std::string::size_type len = str.length();
if(len != 0) {
std::wstring result;
const std::string::size_type len = str.length();
if ( len != 0 ) {
typedef std::ctype< wchar_t > ct_type;
typedef std::wstring::traits_type tr_type;
const ct_type & ct = BOOST_USE_FACET( ct_type, loc );
typedef std::ctype<wchar_t> ct_type;
typedef std::wstring::traits_type tr_type;
const ct_type & ct = BOOST_USE_FACET(ct_type, loc);
result.resize(len);
for (std::size_t i = 0; i < len; ++i)
tr_type::assign(result[i], ct.widen(str[i]));
}
return result;
result.resize( len );
for ( std::size_t i = 0; i < len; ++i )
tr_type::assign( result[ i ], ct.widen( str[ i ] ) );
}
return result;
}
#endif
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
template< typename Block >
void
run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
typedef boost::dynamic_bitset< Block > bitset_type;
typedef bitset_test< bitset_type > Tests;
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test<bitset_type> Tests;
//=====================================================================
// Test stream operator<<
{
// The test "variables" are: the stream type and its state, the
// exception mask, the width, the fill char and the padding side (left/right)
//=====================================================================
// Test stream operator<<
{
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
// The test "variables" are: the stream type and its state, the
// exception mask, the width, the fill char and the padding side (left/right)
static std::string strings[] = {
std::string( "" ),
std::string( "0" ),
std::string( "1" ),
std::string( "11100" ),
get_long_string()
};
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
char fill_chars[] = { '*', 'x', ' ' };
static std::string strings[] = {
std::string(""),
std::string("0"),
std::string("1"),
std::string("11100"),
get_long_string()
};
std::size_t num_masks = sizeof( masks ) / sizeof( masks[ 0 ] );
std::size_t num_strings = sizeof( strings ) / sizeof( strings[ 0 ] );
std::size_t num_chars = sizeof( fill_chars ) / sizeof( fill_chars[ 0 ] );
char fill_chars[] = { '*', 'x', ' ' };
std::fstream not_good_stream( "dynamic_bitset_tests - this file shouldn't exist", std::ios::in );
std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
std::size_t num_chars = sizeof(fill_chars) / sizeof(fill_chars[0]);
for ( std::size_t mi = 0; mi < num_masks; ++mi ) {
for ( std::size_t si = 0; si < num_strings; ++si ) {
std::streamsize slen = (std::streamsize)( strings[ si ].length() );
std::fstream not_good_stream("dynamic_bitset_tests - this file shouldn't exist",
std::ios::in);
assert( ( std::numeric_limits< std::streamsize >::max )() >= (std::streamsize)( 1 + slen * 2 ) );
for ( std::size_t ci = 0; ci < num_chars; ++ci ) {
// note how "negative widths" are tested too
const std::streamsize widths[] = { -1 - slen / 2, 0, slen / 2, 1 + slen * 2 };
std::size_t num_widths = sizeof( widths ) / sizeof( widths[ 0 ] );
for (std::size_t mi = 0; mi < num_masks; ++mi) {
for (std::size_t si = 0; si < num_strings; ++si) {
for ( std::size_t wi = 0; wi < num_widths; ++wi ) {
std::streamsize w = widths[ wi ];
{
// test 0 - stream !good()
if ( not_good_stream.good() )
throw std::logic_error( "Error in operator << tests"
" - please, double check" );
bitset_type b( strings[ si ] );
not_good_stream.width( w );
not_good_stream.fill( fill_chars[ ci ] );
try {
not_good_stream.exceptions( masks[ mi ] );
} catch ( ... ) {
}
std::streamsize slen = (std::streamsize)(strings[si].length());
assert( (std::numeric_limits<std::streamsize>::max)()
>=(std::streamsize)(1+slen*2) );
for (std::size_t ci = 0; ci < num_chars; ++ci) {
// note how "negative widths" are tested too
const std::streamsize widths[] = { -1 - slen/2, 0, slen/2, 1 + slen*2 };
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
for (std::size_t wi = 0; wi < num_widths; ++wi) {
std::streamsize w = widths[wi];
{
// test 0 - stream !good()
if(not_good_stream.good())
throw std::logic_error("Error in operator << tests"
" - please, double check");
bitset_type b(strings[si]);
not_good_stream.width(w);
not_good_stream.fill(fill_chars[ci]);
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
Tests::stream_inserter(b, not_good_stream, "<unused_string>");
}
{
// test 1a - file stream
bitset_type b(strings[si]);
std::ofstream file(test_file_name(), std::ios::trunc);
file.width(w);
file.fill(fill_chars[ci]);
file.exceptions(masks[mi]);
Tests::stream_inserter(b, file, test_file_name());
}
{
//NOTE: there are NO string stream tests
}
#if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
{
// test 1b - wide file stream
bitset_type b(strings[si]);
std::wofstream file(test_file_name());
file.width(w);
file.fill(fill_chars[ci]);
file.exceptions(masks[mi]);
Tests::stream_inserter(b, file, test_file_name());
}
Tests::stream_inserter( b, not_good_stream, "<unused_string>" );
}
{
// test 1a - file stream
scoped_temp_file stf;
bitset_type b( strings[ si ] );
std::ofstream file( stf.path().string().c_str(), std::ios::trunc );
file.width( w );
file.fill( fill_chars[ ci ] );
file.exceptions( masks[ mi ] );
Tests::stream_inserter( b, file, stf.path().string().c_str() );
}
{
// NOTE: there are NO string stream tests
}
#if ! defined( BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS )
{
// test 1b - wide file stream
scoped_temp_file stf;
bitset_type b( strings[ si ] );
std::wofstream file( stf.path().string().c_str() );
file.width( w );
file.fill( fill_chars[ ci ] );
file.exceptions( masks[ mi ] );
Tests::stream_inserter( b, file, stf.path().string().c_str() );
}
#endif
}
}
}
} // for (; mi..)
}
}
}
} // for (; mi..)
}
}
//=====================================================================
// Test stream operator>>
{
// The test "variables" are: the stream type, the exception mask,
// the actual contents (and/or state) of the stream, and width.
//
// With few exceptions, each test case consists of writing a different
// assortment of digits and "whitespaces" to a text stream and then checking
// that what was written gets read back unchanged. That's NOT guaranteed by
// the standard, unless the assortment always ends with a '\n' and satisfies
// other conditions (see C99, 7.19.2/2), however it works in practice and is
// a good "real life" test. Some characters, such as '\v' and '\f', are not
// used exactly because they are the ones which will most likely give problems
// on some systems (for instance '\f' could actually be written as a sequence
// of new-lines, and we could never be able to read it back)
//
// Note how the bitset object is not initially empty. That helps checking
// that it isn't erroneously clear()ed by operator>>.
//=====================================================================
// Test stream operator>>
{
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
// The test "variables" are: the stream type, the exception mask,
// the actual contents (and/or state) of the stream, and width.
//
// With few exceptions, each test case consists of writing a different
// assortment of digits and "whitespaces" to a text stream and then checking
// that what was written gets read back unchanged. That's NOT guaranteed by
// the standard, unless the assortment always ends with a '\n' and satisfies
// other conditions (see C99, 7.19.2/2), however it works in practice and is
// a good "real life" test. Some characters, such as '\v' and '\f', are not
// used exactly because they are the ones which will most likely give problems
// on some systems (for instance '\f' could actually be written as a sequence
// of new-lines, and we could never be able to read it back)
//
// Note how the bitset object is not initially empty. That helps checking
// that it isn't erroneously clear()ed by operator>>.
const std::string spaces = "\t\n "; //"\t\n\v\f ";
const std::string long_string = get_long_string();
const static std::string strings[] = {
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
const std::string spaces = "\t\n "; //"\t\n\v\f ";
const std::string long_string = get_long_string();
/*const*/ static std::string strings[] = {
// NOTE: "const" gives the usual problems with Borland
// (in Tests::stream_extractor instantiation)
#if !(defined __BORLANDC__ \
&& BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)))
// Borland 5.5.1 with RW library crashes
// empty string
std::string(""),
std::string( "" ),
// no bitset
spaces,
#endif
// no bitset
std::string("x"),
std::string("\t xyz"),
std::string( "x" ),
std::string( "\t xyz" ),
// bitset of size 1
std::string("0"),
std::string("1"),
std::string( "0" ),
std::string( "1" ),
std::string(" 0 "),
std::string(" 1 "),
std::string( " 0 " ),
std::string( " 1 " ),
spaces + "1",
"1" + spaces,
spaces + "1" + spaces,
std::string(" x1x "),
std::string(" 1x "),
std::string( " x1x " ),
std::string( " 1x " ),
// long bitset
long_string,
" " + long_string + " xyz",
spaces + long_string,
spaces + long_string + spaces
};
};
//-----------------------------------------------------
//-----------------------------------------------------
std::stringstream not_good_stream;
not_good_stream << "test";
std::string sink;
not_good_stream >> sink; // now the stream should be in eof state
std::stringstream not_good_stream;
not_good_stream << "test";
std::string sink;
not_good_stream >> sink; // now the stream should be in eof state
const std::size_t num_masks = sizeof( masks ) / sizeof( masks[ 0 ] );
const std::size_t num_strings = sizeof( strings ) / sizeof( strings[ 0 ] );
const std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
const std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
for ( std::size_t mi = 0; mi < num_masks; ++mi ) {
for ( std::size_t si = 0; si < num_strings; ++si ) {
const std::streamsize slen = (std::streamsize)( strings[ si ].length() );
assert( ( std::numeric_limits< std::streamsize >::max )() >= (std::streamsize)( 1 + slen * 2 ) );
for (std::size_t mi = 0; mi < num_masks; ++mi) {
for (std::size_t si = 0; si < num_strings; ++si) {
std::streamsize widths[] = { -1, 0, slen / 2, slen, 1 + slen * 2 };
std::size_t num_widths = sizeof( widths ) / sizeof( widths[ 0 ] );
const std::streamsize slen = (std::streamsize)(strings[si].length());
assert((std::numeric_limits<std::streamsize>::max)() >= (std::streamsize)(1+slen*2));
for ( std::size_t wi = 0; wi < num_widths; ++wi ) {
const std::streamsize w = widths[ wi ];
std::streamsize widths[] = { -1, 0, slen/2, slen, 1 + slen*2 };
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
// test 0 - !good() stream
{
if ( not_good_stream.good() )
throw std::logic_error( "Error in operator >> tests"
" - please, double check" );
bitset_type b( 1, 15ul ); // note: b is not empty
not_good_stream.width( w );
try {
not_good_stream.exceptions( masks[ mi ] );
} catch ( ... ) {
}
std::string irrelevant;
Tests::stream_extractor( b, not_good_stream, irrelevant );
}
// test 1a - (narrow) file stream
{
scoped_temp_file stf;
bitset_type b( 1, 255ul );
{
std::ofstream f( stf.path().string().c_str() );
f << strings[ si ];
}
for(std::size_t wi = 0; wi < num_widths; ++wi) {
const std::streamsize w = widths[wi];
// test 0 - !good() stream
{
if(not_good_stream.good())
throw std::logic_error("Error in operator >> tests"
" - please, double check");
bitset_type b(1, 15ul); // note: b is not empty
not_good_stream.width(w);
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
std::string irrelevant;
Tests::stream_extractor(b, not_good_stream, irrelevant);
}
// test 1a - (narrow) file stream
{
bitset_type b(1, 255ul);
{
std::ofstream f(test_file_name());
f << strings[si];
}
std::ifstream f(test_file_name());
f.width(w);
f.exceptions(masks[mi]);
Tests::stream_extractor(b, f, strings[si]);
}
#if !defined(BOOST_NO_STRINGSTREAM)
// test 2a - stringstream
{
bitset_type b(1, 255ul);
std::istringstream stream(strings[si]);
stream.width(w);
stream.exceptions(masks[mi]);
Tests::stream_extractor(b, stream, strings[si]);
}
std::ifstream f( stf.path().string().c_str() );
f.width( w );
f.exceptions( masks[ mi ] );
Tests::stream_extractor( b, f, strings[ si ] );
}
#if ! defined( BOOST_NO_STRINGSTREAM )
// test 2a - stringstream
{
bitset_type b( 1, 255ul );
std::istringstream stream( strings[ si ] );
stream.width( w );
stream.exceptions( masks[ mi ] );
Tests::stream_extractor( b, stream, strings[ si ] );
}
#endif
#if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
// test 1b - wchar_t file stream
{
std::wstring wstr = widen_string(strings[si]);
bitset_type b(1, 255ul);
{
std::basic_ofstream<wchar_t> of(test_file_name());
of << wstr;
}
#if ! defined( BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS )
// test 1b - wchar_t file stream
{
scoped_temp_file stf;
std::wstring wstr = widen_string( strings[ si ] );
bitset_type b( 1, 255ul );
{
std::basic_ofstream< wchar_t > of( stf.path().string().c_str() );
of << wstr;
}
std::basic_ifstream<wchar_t> f(test_file_name());
f.width(w);
f.exceptions(masks[mi]);
Tests::stream_extractor(b, f, wstr);
}
// test 2b - wstringstream
{
bitset_type b(1, 255ul);
std::wstring wstr = widen_string(strings[si]);
std::basic_ifstream< wchar_t > f( stf.path().string().c_str() );
f.width( w );
f.exceptions( masks[ mi ] );
Tests::stream_extractor( b, f, wstr );
}
// test 2b - wstringstream
{
bitset_type b( 1, 255ul );
std::wstring wstr = widen_string( strings[ si ] );
std::wistringstream wstream(wstr);
wstream.width(w);
wstream.exceptions(masks[mi]);
Tests::stream_extractor(b, wstream, wstr);
}
std::wistringstream wstream( wstr );
wstream.width( w );
wstream.exceptions( masks[ mi ] );
Tests::stream_extractor( b, wstream, wstr );
}
#endif // BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
}
}
}
} // for ( mi = 0; ...)
}
} // for ( mi = 0; ...)
}
//=====================================================================
// << Any other tests go here >>
// .....
//=====================================================================
// << Any other tests go here >>
// .....
}
int
test_main(int, char*[])
main()
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
run_test_cases< unsigned char >();
run_test_cases< unsigned short >();
run_test_cases< unsigned int >();
run_test_cases< unsigned long >();
#ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type >();
#endif
return 0;
return boost::report_errors();
}

View File

@@ -10,102 +10,104 @@
//
// -----------------------------------------------------------
#include "boost/config.hpp"
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#endif
#include "bitset_test.hpp"
#include "boost/archive/binary_iarchive.hpp"
#include "boost/archive/binary_oarchive.hpp"
#include "boost/archive/xml_iarchive.hpp"
#include "boost/archive/xml_oarchive.hpp"
#include "boost/config.hpp"
#include "boost/config/workaround.hpp"
#include "boost/dynamic_bitset/serialization.hpp"
#include "boost/detail/workaround.hpp"
#include "boost/serialization/vector.hpp"
// Codewarrior 8.3 for Win fails without this.
// Thanks Howard Hinnant ;)
#if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
# pragma parse_func_templ off
#if ! defined( BOOST_NO_STRINGSTREAM )
# include <sstream>
#endif
#if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
# define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
# define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
#endif
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <sstream>
namespace {
template <typename Block>
struct SerializableType {
boost::dynamic_bitset<Block> x;
template< typename Block >
struct SerializableType
{
boost::dynamic_bitset< Block > x;
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int) {
ar & BOOST_SERIALIZATION_NVP(x);
}
};
private:
friend class boost::serialization::access;
template< class Archive >
void
serialize( Archive & ar, unsigned int )
{
ar & BOOST_SERIALIZATION_NVP( x );
}
};
template <typename Block, typename IArchive, typename OArchive>
void test_serialization( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
SerializableType<Block> a;
template< typename Block, typename IArchive, typename OArchive >
void
test_serialization( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
SerializableType< Block > a;
for (int i=0; i<128; ++i)
a.x.resize(11*i, i%2);
for ( int i = 0; i < 128; ++i )
a.x.resize( 11 * i, i % 2 );
#if !defined (BOOST_NO_STRINGSTREAM)
std::stringstream ss;
#if ! defined( BOOST_NO_STRINGSTREAM )
std::stringstream ss;
// test serialization
{
OArchive oa(ss);
oa << BOOST_SERIALIZATION_NVP(a);
}
// test serialization
{
OArchive oa( ss );
oa << BOOST_SERIALIZATION_NVP( a );
}
// test de-serialization
{
IArchive ia(ss);
SerializableType<Block> b;
ia >> BOOST_SERIALIZATION_NVP(b);
// test de-serialization
{
IArchive ia( ss );
SerializableType< Block > b;
ia >> BOOST_SERIALIZATION_NVP( b );
assert(a.x == b.x);
}
BOOST_TEST( a.x == b.x );
}
#else
# error "TODO implement file-based test path?"
# error "TODO implement file-based test path?"
#endif
}
template <typename Block>
void test_binary_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) {
test_serialization<Block, boost::archive::binary_iarchive, boost::archive::binary_oarchive>();
}
template <typename Block>
void test_xml_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) {
test_serialization<Block, boost::archive::xml_iarchive, boost::archive::xml_oarchive>();
}
}
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
template< typename Block >
void
test_binary_archive( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
test_binary_archive<Block>();
test_xml_archive<Block>();
test_serialization< Block, boost::archive::binary_iarchive, boost::archive::binary_oarchive >();
}
int test_main(int, char*[])
template< typename Block >
void
test_xml_archive( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return 0;
test_serialization< Block, boost::archive::xml_iarchive, boost::archive::xml_oarchive >();
}
}
template< typename Block >
void
run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
{
test_binary_archive< Block >();
test_xml_archive< Block >();
}
int
main()
{
run_test_cases< unsigned char >();
run_test_cases< unsigned short >();
run_test_cases< unsigned int >();
run_test_cases< unsigned long >();
#ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type >();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,26 @@
//
// Copyright (C) 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include "boost/core/lightweight_test.hpp"
#include "boost/dynamic_bitset.hpp"
int
main( int, char *[] )
{
boost::dynamic_bitset<> x( 5 ); // all 0's by default
x.set( 1, 2 );
x.set( 3, 1, true );
x.set( 2, 1, false );
BOOST_TEST( ! x.test( 0 ) );
BOOST_TEST( x.test( 1 ) );
BOOST_TEST( ! x.test( 2 ) );
BOOST_TEST( x.test( 3 ) );
BOOST_TEST( ! x.test( 4 ) );
return boost::report_errors();
}

43
test/test_boost_hash.cpp Normal file
View File

@@ -0,0 +1,43 @@
//
// Copyright (C) 2019 James E. King III
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include "boost/config.hpp"
#include "boost/core/lightweight_test.hpp"
#include "boost/dynamic_bitset.hpp"
#include <set>
int
main( int, char *[] )
{
typedef boost::dynamic_bitset< unsigned long > bitset_type;
const std::string long_string =
"01001110101110110101011010000000000011110101101111111111";
const std::string long_string_prime_begin =
"11001110101110110101011010000000000011110101101111111111";
const std::string long_string_prime_end =
"01001110101110110101011010000000000011110101101111111110";
bitset_type zeroes( long_string.size(), 0 );
bitset_type stuff( long_string );
bitset_type stupb( long_string_prime_begin );
bitset_type stupe( long_string_prime_end );
bitset_type ones( long_string.size(), 1 );
boost::hash< bitset_type > bitset_hasher;
std::set< std::size_t > results;
results.insert( bitset_hasher( zeroes ) );
results.insert( bitset_hasher( stuff ) );
results.insert( bitset_hasher( stupb ) );
results.insert( bitset_hasher( stupe ) );
results.insert( bitset_hasher( ones ) );
// if any hash is identical to another there will be less than 5
BOOST_TEST_EQ( results.size(), 5 );
return boost::report_errors();
}

24
test/test_lowest_bit.cpp Normal file
View File

@@ -0,0 +1,24 @@
//
// Copyright (C) 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include "boost/core/lightweight_test.hpp"
#include "boost/cstdint.hpp"
#include "boost/dynamic_bitset/detail/lowest_bit.hpp"
int
main( int, char *[] )
{
for ( boost::int32_t i = 1; i < 32; ++i ) {
BOOST_TEST_EQ( i, boost::detail::lowest_bit( 1u << i ) );
}
BOOST_TEST_EQ( 2, boost::detail::lowest_bit( 123456788 ) );
BOOST_TEST_EQ( 30, boost::detail::lowest_bit( static_cast< boost::int64_t >( 1507208177123328 ) ) );
return boost::report_errors();
}

33
test/test_std_hash.cpp Normal file
View File

@@ -0,0 +1,33 @@
//
// Copyright (C) 2019 James E. King III
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include "boost/config.hpp"
#include "boost/detail/lightweight_test.hpp"
#include "boost/dynamic_bitset.hpp"
#include <unordered_set>
int
main( int, char *[] )
{
typedef boost::dynamic_bitset< unsigned long > bitset_type;
const std::string long_string =
"01001110101110110101011010000000000011110101101111111111";
bitset_type zeroes( long_string.size(), 0 );
bitset_type stuff( long_string );
bitset_type ones( long_string.size(), 1 );
std::unordered_set< bitset_type > bitsets;
bitsets.insert( zeroes );
bitsets.insert( stuff );
bitsets.insert( ones );
BOOST_TEST_EQ( bitsets.size(), 3 );
return boost::report_errors();
}