Compare commits

...

129 Commits

Author SHA1 Message Date
Gennaro Prota
c13a99640a Try a workaround to have MrDocs document the specialization of std::hash 2025-09-16 10:53:23 +02:00
Gennaro Prota
11088d0d80 Remove extra parentheses in the implementation of operator<()
Reason: Consistency.
2025-09-15 19:23:49 +02:00
Gennaro Prota
fa3cef5485 Add missing spaces in a comment
Reason: Consistency.
2025-09-15 19:23:49 +02:00
Gennaro Prota
4157a327d9 Simplify the implementation of all() 2025-09-15 19:23:49 +02:00
Gennaro Prota
eea6992389 Remove a reference to a removed comment
The referenced comment was removed when porting the documentation to
MrDocs. It advised against using the constructor from basic_string, but,
perhaps, that advice was a bit too strong (constructing from strings is
handy, and probably faster than inputting from a stringstream).
2025-09-15 19:23:49 +02:00
Gennaro Prota
87ea757f7b Add trailing periods to the \pre paragraphs that missed them
Reason: Consistency.
2025-09-15 19:22:48 +02:00
Gennaro Prota
8b729ca3ff Fix a few documentation glitches 2025-09-15 17:18:18 +02:00
Gennaro Prota
a6a7ffa9e6 Make the three "from string" constructors explicit
Making them non-explicit was an oversight.
2025-09-15 12:13:43 +02:00
Gennaro Prota
228d39efd2 Settle the documentation of the iterators
We choose to hide the iterator type definitions and just document their
category, which is enough.
2025-09-15 12:07:27 +02:00
Gennaro Prota
09b7ca2135 Improve the encapsulation of bit_iterator_base 2025-09-12 19:48:15 +02:00
Gennaro Prota
71eaf3136b Fix an error in the documentation of operator==() 2025-09-12 18:33:05 +02:00
Gennaro Prota
ca06119e71 Remove the dependency on core/allocator_access.hpp 2025-09-12 16:34:25 +02:00
Gennaro Prota
fae1e7f97a Make the max_size() tests a bit more meaningful 2025-09-12 11:53:01 +02:00
Gennaro Prota
94eef0dd8d Add a missing comment 2025-09-12 11:41:26 +02:00
Gennaro Prota
f3526cb606 Add push_front() and pop_front() 2025-09-12 11:10:33 +02:00
Gennaro Prota
d79c7f992d No longer use BOOST_NO_CXX11_RVALUE_REFERENCES
Reason: We require decent C++11 support anyway.
2025-09-12 10:42:05 +02:00
Gennaro Prota
ce3435f662 Add two blank lines
Reason: Readability, consistency.
2025-09-12 10:25:30 +02:00
Gennaro Prota
c3a0cc2a32 Make the descriptions of the preconditions of the three "from string" constructors more precise 2025-09-12 10:19:51 +02:00
Gennaro Prota
bd36e481d8 Add a constructor from basic_string_view in C++17 or later
Note that we have MrDocs compile as C++17 again (a change that we had
reverted).
2025-09-12 10:19:51 +02:00
Gennaro Prota
0d0e881254 Add a constructor from const CharT * (pointer to C-style string)
This is in preparation of the next commit, which will add a constructor
from std::basic_string_view (otherwise, construction from a C-style
string would be ambiguous between the basic_string_view and the
basic_string constructor).

Note that, rather than duplicating code to test the new member, we
changed many constructions in dyn_bitset_unit_tests1.cpp to use const
char *, instead of std::string. (The constructor from std::basic_string
is tested separately anyway.)
2025-09-12 10:19:51 +02:00
Gennaro Prota
ba12d33c84 Don't test for Tr::eq( c, one ) twice in init_from_string() 2025-09-12 10:19:51 +02:00
Gennaro Prota
36d52d6b00 No longer use boost::move()
Reason: We require C++11 now, so we can use std::move().
2025-09-12 10:19:51 +02:00
Gennaro Prota
95e06608e1 Actually test the move constructor in the move constructor tests
We were testing the *copy* constructor, instead.
2025-09-12 10:19:51 +02:00
Gennaro Prota
21eda71789 Replace a #include of a deprecated include file 2025-09-12 10:19:51 +02:00
Gennaro Prota
8587d4f97c Remove a superfluous #include directive 2025-09-12 10:19:51 +02:00
Gennaro Prota
c442ecdc90 Add missing const qualifiers 2025-09-12 10:19:51 +02:00
Gennaro Prota
ed2f5281fe Make lowest_bit() more efficient
As a nice bonus, this also removes the dependency on Boost.Integer.
2025-09-12 10:19:51 +02:00
Gennaro Prota
fd95d1b570 Remove a spurious space 2025-09-12 10:19:51 +02:00
Gennaro Prota
a02393bd26 Fix a misleading variable name 2025-09-12 10:19:51 +02:00
Gennaro Prota
d7ba1ffd13 Get rid of BOOST_STATIC_ASSERT() and BOOST_STATIC_CONSTANT()
Reason: They are no longer necessary, given that we require C++11 now.
2025-09-12 10:19:51 +02:00
Gennaro Prota
6ef22fc69c Assert that Block is the same type as AllocatorOrContainer::value_type
Reason: That's required both when AllocatorOrContainer is an allocator
type and when it's a container type. Now, when it is an allocator type,
the assert is usually in the implementation of std::vector, which we
use. But, when it's a container type, we need to assert that on our own.
2025-09-12 10:19:51 +02:00
Gennaro Prota
6a5faf3597 Remove the parameter-less overloads of find_first() and find_first_off()
Reason: We can use a default argument, instead, which is what
dynamic_bitset usually does.
2025-09-12 10:19:51 +02:00
Gennaro Prota
399230316c Make pop_back() more efficient 2025-09-12 10:19:51 +02:00
Gennaro Prota
f997c1fa7f Back out the support for operator<=> in our iterators
Reason: It required operator<=> for the underlying container, and
boost::container::small_vector doesn't support it.
2025-09-12 10:19:51 +02:00
Gennaro Prota
969c7e0947 Make buffer_type public
Reason: Failures from GCC and Clang. See the new code comment.
2025-09-12 10:19:51 +02:00
Gennaro Prota
7668759686 Remove some outdated macros (workarounds for MSVC 6) 2025-09-12 10:19:51 +02:00
Gennaro Prota
7144965095 Remove another workaround for Codewarrior 8.3
Reason: Obsolete compiler.
2025-09-12 10:19:51 +02:00
Gennaro Prota
b0b94ec560 Add C++20 iterators
Reason: Requested on the mailing list.
2025-09-12 10:19:51 +02:00
Gennaro Prota
1f6e471132 Allow choosing the underlying container type
The user can now choose the underlying container used by dynamic_bitset.
This allows e.g. having small buffer optimization by using
boost::container::small_vector.

Since the underlying container is no longer guaranteed to be
std::vector, we revert "Reflect some noexcept specifications of
std::vector in dynamic_bitset" and the related "Let MrDocs compile the
code as C++17".

Note that we didn't add serialization tests (dyn_bitset_unit_tests5.cpp)
because boost::container::small_vector has no serialization support.

This closes issue #76.
2025-09-12 10:19:51 +02:00
Gennaro Prota
467e121a68 Add find_first_off(), find_first_off( size_type ) and find_next_off( size_type ) 2025-09-12 10:19:51 +02:00
Gennaro Prota
c12ffc8b37 Don't repeat the preprocessing condition to specialize std::hash 2025-09-12 10:19:51 +02:00
Alan de Freitas
dc2a88e9a7 Make the MrDocs documentation multipage 2025-09-12 10:19:51 +02:00
Alan de Freitas
1ead020341 Support CMake root mode 2025-09-12 10:19:51 +02:00
Gennaro Prota
0b177806ce Ensure all #includes are at the top of the source file 2025-09-12 10:19:38 +02:00
Gennaro Prota
055631591a Document our support for std::hash 2025-09-12 10:16:34 +02:00
Gennaro Prota
abbecdb56e Remove some symbol filters from mrdocs.yml
Reason: They no longer seem necessary.
2025-09-11 12:49:13 +02:00
Gennaro Prota
7a01d14918 Reword a comment using singular they 2025-09-11 12:49:13 +02:00
Gennaro Prota
9baffa4887 Document that max_size() doesn't emit exceptions 2025-09-11 12:49:13 +02:00
Gennaro Prota
baf130a7e6 Use noexcept instead of BOOST_NOEXCEPT
Reason: We require C++11 support anyway.
2025-09-11 12:49:13 +02:00
ivanpanch
9ad6687e9a Fix a typo (“slighly”) in a documentation comment 2025-09-11 12:49:13 +02:00
ivanpanch
fd5e2fae75 Remove a spurious comma in a documentation comment 2025-09-11 12:49:13 +02:00
Gennaro Prota
122c4b986d Avoid an interrupted sentence in the \brief documentation of the stream inserter 2025-09-11 12:49:13 +02:00
Gennaro Prota
495aec32a0 Use the same parameter name for the two overloads of at()
Reason: Consistency.

This incidentally also fixes the documentation of the non-const
overload.
2025-09-11 12:49:13 +02:00
Gennaro Prota
ba8c408b31 Add a missing const qualifier 2025-09-11 12:49:13 +02:00
Gennaro Prota
c63af26734 Fix an error in the documentation of resize() 2025-09-11 12:49:13 +02:00
Gennaro Prota
ff0b3b97f2 Let MrDocs compile the code as C++17
Reason: Getting the noexcept specifications introduced in "Reflect some
noexcept specifications of std::vector in dynamic_bitset".
2025-09-11 12:49:13 +02:00
Gennaro Prota
e8a570b4b4 Work around some glitches from the MrDocs parser 2025-09-11 12:49:13 +02:00
Gennaro Prota
5bba2b7694 Document our overload of hash_value() 2025-09-11 12:49:13 +02:00
Gennaro Prota
4a5dbf29af Fix two typos in the documentation comments 2025-09-11 12:49:13 +02:00
Gennaro Prota
e93f96cc96 Document many function parameters and some return values
For some of these, we were getting "undocumented parameter" warnings
from MrDocs. For others, MrDocs was automatically adding some
documentation, but that was inadequate for DynamicBitset.
2025-09-11 12:49:13 +02:00
Gennaro Prota
edd9091371 Run the Antora workflow on macOS 15, in GitHub Actions 2025-09-11 12:49:13 +02:00
Gennaro Prota
b104747c51 Use the same parameter names in the two declarations of boost::swap()
Reason: Fixing an error from MSVC 14.3 about different noexcept
specifications between the two declarations.
2025-09-11 12:49:13 +02:00
Gennaro Prota
2d33df8f43 Simplify a redundant assert condition 2025-09-11 12:49:13 +02:00
Gennaro Prota
8de7c429c3 Reflect some noexcept specifications of std::vector in dynamic_bitset
This closes issue #85.
2025-09-11 12:49:13 +02:00
Gennaro Prota
b06e995e77 Always use braces with for-statements, as well
Reason: Consistency and safety.

See: "Always use braces with if-statements".
2025-09-11 12:49:13 +02:00
Gennaro Prota
e173eb3531 Denote short and long consistently 2025-09-11 12:49:13 +02:00
Gennaro Prota
a4820c1146 Rename dynamic_bitset.tpp to "dynamic_bitset.ipp"
Reason: Having it copied at installation time.
2025-09-11 12:49:13 +02:00
Gennaro Prota
3ed154a1bd Leave inline to the compiler 2025-09-11 12:49:13 +02:00
Gennaro Prota
b18ddca496 Set badbit if an exception is thrown during output
Reason: This is what the standard formatted output functions do.
2025-09-11 12:49:13 +02:00
Gennaro Prota
3d7458554d Remove two erroneous references to the standard 2025-09-11 12:49:13 +02:00
Gennaro Prota
683e160337 Move a few includes to where they are actually used 2025-09-11 12:49:13 +02:00
Gennaro Prota
0187aa3d16 Always use braces with if-statements
Reason: Consistency and safety.
2025-09-11 12:49:13 +02:00
Gennaro Prota
1cb4f79f55 Fix a typo in the documentation of operator>>=() 2025-09-11 12:49:13 +02:00
Gennaro Prota
3b14784fa0 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-09-11 12:49:13 +02:00
Gennaro Prota
915950efb8 Add two missing spaces in a documentation comment 2025-09-11 12:49:13 +02:00
Gennaro Prota
a44af50e30 Also exclude bit_appender from the MrDocs documentation 2025-09-11 12:49:13 +02:00
Gennaro Prota
59c40f1978 Remove a pair of unneeded parentheses 2025-09-11 12:49:13 +02:00
Sébastien Loriot
6aafdcf80e qualify full path 2025-09-11 12:49:13 +02:00
Gennaro Prota
1eea7dc9e9 Fix nav.adoc 2025-09-11 12:49:13 +02:00
Gennaro Prota
f7237d08f2 Add a few links to the reference in the documentation index 2025-09-11 12:49:13 +02:00
Gennaro Prota
13693afa74 Add doc/package.json and doc/package-lock.json 2025-09-11 12:49:13 +02:00
Gennaro Prota
de0d6f1745 Exclude old, failing versions of Clang and GCC from CI 2025-09-11 12:49:13 +02:00
Gennaro Prota
023055938c Also build the documentation in the CI workflow 2025-09-11 12:49:13 +02:00
James E. King III
6a3775e91c 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-09-11 12:49:13 +02:00
Gennaro Prota
3673eb67af Rethrow any exception coming from the underlying vector, in the stream extractor 2025-09-11 12:49:13 +02:00
Gennaro Prota
4bd3dd25d6 Delete unary operator&() for dynamic_bitset::reference
Reason: That's better than declaring it as private and leaving it
undefined.
2025-09-11 12:49:13 +02:00
Gennaro Prota
85678044f2 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-09-11 12:49:13 +02:00
Gennaro Prota
2c5d4dafc5 Add a missing blank line 2025-09-11 12:49:13 +02:00
Gennaro Prota
3cdaaa77df Remove an unnecessary constructor definition 2025-09-11 12:49:13 +02:00
Gennaro Prota
dd5426c4a6 Remove an unnecessary implementation detail 2025-09-11 12:49:13 +02:00
Gennaro Prota
5d321779f8 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-09-11 12:49:13 +02:00
Gennaro Prota
e90c7c5074 Make scoped_temp_file non-copyable, as it should 2025-09-11 12:49:13 +02:00
Gennaro Prota
27c94d5a31 Remove a nonsensical typedef 2025-09-11 12:49:12 +02:00
Gennaro Prota
1cc0ea2d18 Don't use lowerCamelCase for template type parameters 2025-09-11 12:49:12 +02:00
Gennaro Prota
7f88f43c3e Copy edit a comment 2025-09-11 12:49:12 +02:00
Gennaro Prota
e478613276 Remove a few unneeded permission notices 2025-09-11 12:49:12 +02:00
Gennaro Prota
970624a2fe Port the documentation to MrDocs and Antora 2025-09-11 12:49:12 +02:00
Gennaro Prota
9cbb307df1 Reformat all the C++ code (with ClangFormat) 2025-09-11 12:49:12 +02:00
Gennaro Prota
e6eb4d62e7 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-09-11 12:49:12 +02:00
Gennaro Prota
7df7ebd808 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-09-11 12:49:04 +02:00
Gennaro Prota
5bd37d352a Leverage core::popcount() in the implementation of count()
Reason: This significantly simplifies the code, replacing a previous
complex and error-prone implementation.
2025-09-11 12:36:49 +02:00
Gennaro Prota
ad7d867a83 Fix some inconsistent placement of const qualifiers 2025-09-11 12:36:49 +02:00
Gennaro Prota
f56b3dde37 Assert on the precondition to pop_back() 2025-09-11 12:36:49 +02:00
Gennaro Prota
32ae43ef6d Make the swap() functions noexcept 2025-09-11 12:36:49 +02:00
Gennaro Prota
92789a9f61 Remove a misleading comment 2025-09-11 12:36:49 +02:00
Gennaro Prota
f801c2ced8 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-09-11 12:36:49 +02:00
Gennaro Prota
6e17428110 Remove a top-level const qualifier for a function parameter 2025-09-11 12:36:49 +02:00
Gennaro Prota
0f3612bd4a Add a missing const qualifier in a test function 2025-09-11 12:36:49 +02:00
Gennaro Prota
be94d262e4 Use BOOST_TEST(), not assert(), for test cases 2025-09-11 12:36:49 +02:00
Gennaro Prota
8235c9c523 Remove other workarounds for obsolete compilers 2025-09-11 12:36:49 +02:00
Gennaro Prota
072714abdc 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-09-11 12:36:49 +02:00
Gennaro Prota
a87502c04f Clean up detail/lowest_bit.hpp (mostly, reformat) 2025-09-11 12:36:49 +02:00
Gennaro Prota
98964c77c9 Remove a naive comment
If you are asserting on it at the beginning of the function, it's
clearly a precondition :-).
2025-09-11 12:36:49 +02:00
Gennaro Prota
68e48485b2 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-09-11 12:36:49 +02:00
Gennaro Prota
2c31089bb2 Remove inconsistent uses of title case 2025-09-11 12:36:49 +02:00
Gennaro Prota
cdbcfd3853 Remove trailing whitespace 2025-09-11 12:36:48 +02:00
Gennaro Prota
55ca6c1449 Remove an unneeded #include directive in a test file 2025-09-11 12:36:48 +02:00
Gennaro Prota
20a866a032 Remove a tab character in a test file 2025-09-11 12:36:48 +02:00
Gennaro Prota
bf53144cd7 Remove a superfluous #include directive 2025-09-11 12:36:48 +02:00
Gennaro Prota
8d5dee07be Remove superfluous parentheses around a macro name 2025-09-11 12:36:48 +02:00
Gennaro Prota
e16b7bf01a Copy edit the readme
Note how I removed the "Directories" paragraph, as it just stated the
obvious.
2025-09-11 12:36:48 +02:00
Gennaro Prota
0a3198a2f0 Remove an unused, junk function template 2025-09-11 12:36:48 +02:00
Gennaro Prota
17bf6c27c8 Consistently use BOOST_ASSERT() in the implementation
Note: Not in the unit tests, which better do without the dependency.
2025-09-11 12:36:48 +02:00
Gennaro Prota
174050bee8 Remove a workaround for CodeWarrior 8 2025-09-11 12:36:48 +02:00
Gennaro Prota
9e164b9db7 Remove a spurious #undef directive
The #undef'd macro wasn't actually defined anywhere.
2025-09-11 12:36:48 +02:00
Gennaro Prota
b051052884 Declare some internal details as private
They had been accidentally made public.
2025-09-11 12:36:48 +02:00
Gennaro Prota
f2db3e80d6 Remove some redundant access specifiers 2025-09-11 12:36:48 +02:00
Gennaro Prota
a9a0d152d9 Remove a hopefully outdated workaround 2025-09-11 12:36:48 +02:00
Gennaro Prota
240c721d88 Remove a nonsensical usage of boost::addressof
Because `dynamic_bitset` doesn't overload unary `operator &`.
2025-09-11 12:36:48 +02:00
36 changed files with 10653 additions and 7933 deletions

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:

View File

@@ -1,12 +1,21 @@
#
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 Andrey Semashev
# Copyright 2021 Alexander Grund
# Copyright 2022-2024 James E. King III
# 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: CI
name: Boost.CI
on:
pull_request:
@@ -23,407 +32,79 @@ on:
- meta/**
- README.md
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
B2_CI_VERSION: 1
B2_VARIANT: debug,release
B2_LINK: shared,static
LCOV_BRANCH_COVERAGE: 0
jobs:
posix:
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-15 }
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# linux, gcc
- { compiler: gcc-7, cxxstd: '11,14,17', os: ubuntu-20.04 }
- { compiler: gcc-8, cxxstd: '11,14,17,2a', os: ubuntu-20.04 }
- { compiler: gcc-9, cxxstd: '11,14,17,2a', os: ubuntu-20.04 }
- { compiler: gcc-10, cxxstd: '11,14,17,20', os: ubuntu-20.04 }
- { compiler: gcc-11, cxxstd: '11,14,17,20', os: ubuntu-20.04 }
- { compiler: gcc-12, cxxstd: '11,14,17,20', os: ubuntu-22.04 }
- { compiler: gcc-13, cxxstd: '11,14,17,20,2b', os: ubuntu-22.04 }
- { compiler: gcc-14, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04 }
- { name: GCC w/ sanitizers, sanitize: yes,
compiler: gcc-13, cxxstd: '11,14,17,20', os: ubuntu-22.04 }
- { name: Collect coverage, coverage: yes,
compiler: gcc-12, cxxstd: '11', os: ubuntu-22.04, install: 'g++-12-multilib', address-model: '32,64' }
# linux, clang
- { compiler: clang-9, cxxstd: '11,14,17,2a', os: ubuntu-20.04 }
- { compiler: clang-10, cxxstd: '11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-11, cxxstd: '11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-12, cxxstd: '11,14,17,20', os: ubuntu-20.04 }
# Clang isn't compatible with libstdc++-13, so use the slightly older one
- { compiler: clang-13, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-13 g++-12', gcc_toolchain: 12 }
- { compiler: clang-14, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-14 g++-12', gcc_toolchain: 12 }
- { compiler: clang-15, cxxstd: '11,14,17,20', os: ubuntu-22.04, install: 'clang-15 g++-12', gcc_toolchain: 12 }
- { compiler: clang-16, cxxstd: '11,14,17,20,2b', os: ubuntu-24.04 }
# https://github.com/llvm/llvm-project/issues/59827: disabled 2b/23 for clang-17 with libstdc++13 in 24.04
- { compiler: clang-17, cxxstd: '11,14,17,20', os: ubuntu-24.04 }
- { compiler: clang-18, cxxstd: '11,17,20,23,2c', os: ubuntu-24.04 }
# linux, libc++
- { name: Clang w/ sanitizers, sanitize: yes,
compiler: clang-12, cxxstd: '11,14,17,20', os: ubuntu-20.04, stdlib: 'libc++', install: 'clang-12 libc++-12-dev libc++abi-12-dev' }
- { name: MacOS w/ clang and sanitizers,
compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-13, sanitize: yes }
- { compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-14 }
- { compiler: clang, cxxstd: '11,14,17,20,2b', os: macos-15 }
# Coverity Scan
# requires two github secrets in repo to activate; see ci/github/coverity.sh
# does not run on pull requests, only on pushes into develop and master
- { name: Coverity, coverity: yes,
compiler: clang-12, cxxstd: '17', os: ubuntu-20.04, ccache: no }
# multiarch (bigendian testing) - does not support coverage yet
- { name: Big-endian, multiarch: yes,
compiler: clang, cxxstd: '17', os: ubuntu-22.04, ccache: no, distro: fedora, edition: 34, arch: s390x }
timeout-minutes: 120
runs-on: ${{matrix.os}}
env: {B2_USE_CCACHE: 1}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]; then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ] && [ -f "/etc/debian_version" ]; then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common curl
# Need (newer) git, and the older Ubuntu container may require requesting the key manually using port 80
curl -sSL --retry ${NET_RETRY_COUNT:-5} 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xE1DD270288B4E6030699E45FA1715D88E1DF1F24' | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/git-core_ubuntu_ppa.gpg
for i in {1..${NET_RETRY_COUNT:-3}}; do sudo -E add-apt-repository -y ppa:git-core/ppa && break || sleep 10; done
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
osver=$(lsb_release -sr | cut -f1 -d.)
pkgs="g++ git xz-utils"
# Ubuntu 22+ has only Python 3 in the repos
if [ -n "$osver" ] && [ "$osver" -ge "22" ]; then
pkgs+=" python-is-python3 libpython3-dev"
else
pkgs+=" python libpython-dev"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs
fi
# For jobs not compatible with ccache, use "ccache: no" in the matrix
if [[ "${{ matrix.ccache }}" == "no" ]]; then
echo "B2_USE_CCACHE=0" >> $GITHUB_ENV
fi
git config --global pack.threads 0
if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then
# Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590
curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217
fi
- uses: actions/checkout@v4
with:
# For coverage builds fetch the whole history, else only 1 commit using a 'fake ternary'
fetch-depth: ${{ matrix.coverage && '0' || '1' }}
- name: Cache ccache
uses: actions/cache@v4
if: env.B2_USE_CCACHE
with:
path: ~/.ccache
key: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-${{github.sha}}
restore-keys: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-
- name: Fetch Boost.CI
uses: actions/checkout@v4
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Install packages
if: startsWith(matrix.os, 'ubuntu')
run: |
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
SOURCES=("${{join(matrix.sources, '" "')}}")
# Add this by default
SOURCE_KEYS+=('http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1E9377A2BA9EF27F')
SOURCES+=(ppa:ubuntu-toolchain-r/test)
uses: alandefreitas/cpp-actions/package-install@v1.8.8
with:
apt-get: git cmake
ci/add-apt-keys.sh "${SOURCE_KEYS[@]}"
# Initial update before adding sources required to get e.g. keys
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
ci/add-apt-repositories.sh "${SOURCES[@]}"
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [[ -z "${{matrix.install}}" ]]; then
pkgs="${{matrix.compiler}}"
pkgs="${pkgs/gcc-/g++-}"
else
pkgs="${{matrix.install}}"
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=$GCC_TOOLCHAIN_ROOT" >> $GITHUB_ENV
if ! command -v dpkg-architecture; then
apt-get install -y dpkg-dev
fi
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup multiarch
if: matrix.multiarch
env:
BDDE_DISTRO: ${{matrix.distro}}
BDDE_EDITION: ${{matrix.edition}}
BDDE_ARCH: ${{matrix.arch}}
run: ci/github/setup_bdde.sh
- name: Setup Boost
env:
B2_ADDRESS_MODEL: ${{matrix.address-model}}
B2_COMPILER: ${{matrix.compiler}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_SANITIZE: ${{matrix.sanitize}}
B2_STDLIB: ${{matrix.stdlib}}
# More entries can be added in the same way, see the B2_ARGS assignment in ci/enforce.sh for the possible keys.
# B2_DEFINES: ${{matrix.defines}}
# Variables set here (to non-empty) will override the top-level environment variables, e.g.
# B2_VARIANT: ${{matrix.variant}}
# Set the (B2) target(s) to build, defaults to the test folder of the current library
# Can alternatively be done like this in the build step or in the build command of the build step, e.g. `run: B2_TARGETS=libs/$SELF/doc ci/build.sh`
# B2_TARGETS: libs/foo/test//bar
run: source ci/github/install.sh
- name: Setup coverage collection
if: matrix.coverage
run: ci/github/codecov.sh "setup"
- name: Run tests
if: '!matrix.coverity'
run: ci/build.sh
- name: Upload coverage
if: matrix.coverage
run: ci/codecov.sh "upload"
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Run coverity
if: matrix.coverity && github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'master')
run: ci/github/coverity.sh
env:
COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
windows:
defaults:
run:
shell: cmd
strategy:
fail-fast: false
matrix:
include:
- { toolset: msvc-14.0, cxxstd: '14,latest', addrmd: '32,64', os: windows-2019 }
- { toolset: msvc-14.2, cxxstd: '14,17,20', addrmd: '32,64', os: windows-2019 }
- { toolset: msvc-14.3, cxxstd: '14,17,20,latest',addrmd: '32,64', os: windows-2022 }
- { name: Collect coverage, coverage: yes,
toolset: msvc-14.3, cxxstd: 'latest', addrmd: '64', os: windows-2022 }
- { toolset: clang-win, cxxstd: '14,17,latest', addrmd: '32,64', os: windows-2022 }
- { toolset: gcc, cxxstd: '11,14,17,2a', addrmd: '64', os: windows-2019 }
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Fetch Boost.CI
- name: Clone Boost.DynamicBitset
uses: actions/checkout@v4
- name: Clone Boost
uses: alandefreitas/cpp-actions/boost-clone@v1.8.8
id: boost-clone
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
REM Copy ci folder if not testing Boost.CI
if "%GITHUB_REPOSITORY%" == "%GITHUB_REPOSITORY:boost-ci=%" xcopy /s /e /q /i /y boost-ci-cloned\ci .\ci
rmdir /s /q boost-ci-cloned
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
boost-dir: ../boost-source
scan-modules-dir: .
scan-modules-ignore: dynamic_bitset
- name: Setup Boost
run: ci\github\install.bat
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Run tests
if: '!matrix.coverage'
run: ci\build.bat
- name: Setup Ninja
if: runner.os == 'Windows'
uses: seanmiddleditch/gha-setup-ninja@v5
- name: Build Antora docs
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global --add safe.directory "$(pwd)"
- name: Collect coverage
shell: powershell
if: matrix.coverage
run: ci\opencppcoverage.ps1
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
cd ..
BOOST_SRC_DIR="$(pwd)/boost-source"
export BOOST_SRC_DIR
- name: Upload coverage
if: matrix.coverage
uses: codecov/codecov-action@v5
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:
disable_search: true
fail_ci_if_error: true
files: __out/cobertura.xml
name: github-actions
token: ${{secrets.CODECOV_TOKEN}}
verbose: true
MSYS2:
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
include:
- { sys: MINGW32, compiler: gcc, cxxstd: '11,17,20' }
- { sys: MINGW64, compiler: gcc, cxxstd: '11,17,20' }
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup MSYS2 environment
uses: msys2/setup-msys2@v2
with:
msystem: ${{matrix.sys}}
update: true
install: git python
pacboy: gcc:p cmake:p ninja:p
- name: Fetch Boost.CI
uses: actions/checkout@v4
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env:
B2_COMPILER: ${{matrix.compiler}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_SANITIZE: ${{matrix.sanitize}}
B2_STDLIB: ${{matrix.stdlib}}
run: ci/github/install.sh
- name: Run tests
run: ci/build.sh
# Run also the CMake tests to avoid having to setup another matrix for CMake on MSYS
- name: Run CMake tests
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --target tests --config Debug -j$B2_JOBS
ctest --output-on-failure --build-config Debug
CMake:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-20.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' }
- { os: ubuntu-20.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' }
- { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' }
- { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' }
timeout-minutes: 120
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Fetch Boost.CI
uses: actions/checkout@v4
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env: {B2_DONT_BOOTSTRAP: 1}
run: source ci/github/install.sh
- name: Run CMake tests
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --target tests --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Run CMake subdir tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test"
cd "$cmake_test_folder"
mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} ..
cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Install Library
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON ..
cmake --build . --target install --config ${{matrix.build_type}} -j$B2_JOBS
- name: Run CMake install tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test"
cd "$cmake_test_folder"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local ..
cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}
name: antora-docs-${{ matrix.name }}
path: doc/build/site

View File

@@ -1,26 +1,67 @@
# 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)
set(BOOST_DYNAMIC_BITSET_IS_ROOT OFF)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(BOOST_DYNAMIC_BITSET_IS_ROOT ON)
endif ()
add_library(boost_dynamic_bitset INTERFACE)
add_library(Boost::dynamic_bitset ALIAS boost_dynamic_bitset)
target_include_directories(boost_dynamic_bitset INTERFACE include)
if (BOOST_DYNAMIC_BITSET_IS_ROOT)
# This means this script will be executed as the root CMakeLists.txt
# so the Boost:: targets are not available unless we explicitly include
# them here. MrDocs executes this script as root too.
if (NOT DEFINED BOOST_SRC_DIR AND DEFINED ENV{BOOST_SRC_DIR})
set(DEFAULT_BOOST_SRC_DIR "$ENV{BOOST_SRC_DIR}")
else ()
set(DEFAULT_BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
endif ()
set(BOOST_SRC_DIR ${DEFAULT_BOOST_SRC_DIR} CACHE STRING "Boost source dir to use when running CMake from this directory")
if (NOT IS_ABSOLUTE ${BOOST_SRC_DIR})
set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_SRC_DIR}")
endif ()
# Validate BOOST_SRC_DIR
set(BOOST_SRC_DIR_IS_VALID ON)
foreach (F "CMakeLists.txt" "Jamroot" "boost-build.jam" "bootstrap.sh" "libs")
if (NOT EXISTS "${BOOST_SRC_DIR}/${F}")
message(STATUS "${BOOST_SRC_DIR}/${F} does not exist. Fallback to find_package.")
set(BOOST_SRC_DIR_IS_VALID OFF)
break()
endif ()
endforeach ()
if (NOT BOOST_SRC_DIR_IS_VALID)
message(FATAL_ERROR "BOOST_SRC_DIR is not valid. Please set it to the root of a Boost checkout.")
endif ()
# If BOOST_SRC_DIR is valid, fallback to find_package
set(CMAKE_FOLDER Dependencies)
set(BOOST_INCLUDE_LIBRARIES assert config container_hash core throw_exception)
set(BOOST_EXCLUDE_LIBRARIES dynamic_bitset)
set(PREV_BUILD_TESTING ${BUILD_TESTING})
set(BUILD_TESTING OFF CACHE BOOL "Build the tests." FORCE)
add_subdirectory(${BOOST_SRC_DIR} Dependencies/boost EXCLUDE_FROM_ALL)
set(BUILD_TESTING ${PREV_BUILD_TESTING} CACHE BOOL "Build the tests." FORCE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${BOOST_SRC_DIR}/tools/cmake/include")
unset(CMAKE_FOLDER)
endif()
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
)
@@ -30,3 +71,26 @@ if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
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})
# This is to get the documentation of the constructor from basic_string_view.
set_target_properties(dynamic_bitset_mrdocs_target PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES)
# 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,4 +1,4 @@
DynamicBitset, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), is similar to std::bitset however the size is specified at run-time instead of at compile-time.
DynamicBitset, part of the [Boost C++ Libraries](https://github.com/boostorg), is a bit vector similar to std::bitset but dynamically resizable.
### License
@@ -9,26 +9,17 @@ Distributed under the [Boost Software License, Version 1.0](https://www.boost.or
* C++11
* Header-only
### Build Status
### Build status
<!-- boost-ci/tools/makebadges.sh --project dynamic_bitset --appveyor n7bki5ka3v918r5r --codecov PVG5jth1ez --coverity 16167 -->
| Branch | GHA CI | Appveyor | Coverity Scan | codecov.io | 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)
### Directories
| Name | Purpose |
| ----------- | ------------------------------ |
| `example` | examples |
| `doc` | documentation |
| `include` | headers |
| `test` | unit tests |
| 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 Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](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.
* [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.

View File

@@ -10,9 +10,6 @@ constant boost_dependencies :
/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

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"

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

@@ -0,0 +1,55 @@
# ============================================================================
# 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'
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,73 @@
// ===========================================================================
// Copyright 2001 Jeremy Siek
// Copyright 2003-2004, 2008, 2025 Gennaro Prota
// Copyright 2014 Ahmed Charles
// Copyright 2014 Riccardo Marcangelo
// Copyright 2018 Evgeny Shulgin
//
// 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
Because of the proxy reference type, `dynamic_bitset` is not a <a
href="https://en.cppreference.com/w/cpp/named_req/Container.html">Container</a>
and its iterators do not satisfy the requirements for a LegacyForwardIterator.
This means that its iterators are not usable with many standard algorithms.
However, `dynamic_bitset` provides C++20 iterators which can be used with
ranges.
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::bit_iterator_base'
- 'boost::bit_iterator'
- 'boost::const_bit_iterator'
- 'boost::detail'
- 'boost::detail::**'
- 'boost::to_string_helper'
- 'boost::dynamic_bitset::bit_appender'
- 'boost::dynamic_bitset::buffer_type'
file-patterns:
- '*.hpp'
multipage: true
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

@@ -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
@@ -20,14 +18,15 @@
#include "boost/dynamic_bitset.hpp"
#include <iostream>
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

@@ -13,19 +13,20 @@
#include "boost/dynamic_bitset.hpp"
#include <iostream>
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 <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

@@ -13,33 +13,25 @@
#define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
// 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 BOOST_BORLANDC && BOOST_WORKAROUND(BOOST_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
@@ -49,19 +41,27 @@ 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
#if ! defined( BOOST_NO_CXX11_HDR_FUNCTIONAL ) && ! defined( BOOST_DYNAMIC_BITSET_NO_STD_HASH )
# define BOOST_DYNAMIC_BITSET_SPECIALIZE_STD_HASH
#endif
#if ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || __cplusplus >= 201703L
# define BOOST_DYNAMIC_BITSET_USE_CPP17_OR_LATER
#endif
#endif // include guard

View File

@@ -17,291 +17,174 @@
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
#include "boost/config.hpp"
#include "boost/core/allocator_access.hpp"
#include "boost/detail/workaround.hpp"
#include <cstddef>
#include <memory>
#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
#include <intrin.h>
#endif
#include <type_traits>
#include <utility>
namespace boost {
namespace detail {
namespace dynamic_bitset_impl {
namespace detail {
namespace dynamic_bitset_impl {
template<class T>
struct max_limit {
BOOST_STATIC_CONSTEXPR T value = static_cast<T>(-1);
template< typename AllocatorOrContainer, typename Block >
class is_container
{
private:
template< typename U >
static decltype(
std::declval< U >().resize( std::size_t{} ),
std::declval< U >()[ 0 ],
typename U::value_type(),
std::is_same< typename U::value_type, Block >{},
std::true_type{}
) test( int );
template< typename >
static std::false_type test( ... );
public:
static constexpr bool value = decltype( test< AllocatorOrContainer >( 0 ) )::value;
};
template< typename AllocatorOrContainer, typename Block, bool IsContainer >
class allocator_type_extractor_impl;
template< typename AllocatorOrContainer, typename Block >
class allocator_type_extractor_impl< AllocatorOrContainer, Block, false >
{
public:
typedef AllocatorOrContainer type;
};
template< typename AllocatorOrContainer, typename Block >
class allocator_type_extractor_impl< AllocatorOrContainer, Block, true >
{
public:
typedef typename AllocatorOrContainer::allocator_type type;
};
template< typename AllocatorOrContainer, typename Block >
class allocator_type_extractor
{
public:
typedef typename allocator_type_extractor_impl<
AllocatorOrContainer,
Block,
is_container< AllocatorOrContainer, Block >::value
>::type type;
};
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 >
typename T::size_type
vector_max_size_workaround( const T & v )
noexcept
{
typedef typename T::allocator_type allocator_type;
const allocator_type & alloc = v.get_allocator();
typename std::allocator_traits< allocator_type >::size_type alloc_max =
std::allocator_traits< allocator_type >::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<class T>
BOOST_CONSTEXPR_OR_CONST T max_limit<T>::value;
// 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)
template<>
struct allowed_block_type< bool >
{
enum
{
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));
}
value = false
};
};
// ------- 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
template< typename T >
struct is_numeric
{
enum
{
value_to_type() {}
value = false
};
const bool access_by_bytes = true;
const bool access_by_blocks = false;
};
#define BOOST_dynamic_bitset_is_numeric( x ) \
template<> \
struct is_numeric< x > \
{ \
enum \
{ \
value = true \
}; \
} /**/
// 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
};
// Some platforms have fast popcount operation, that allow us to implement
// counting bits much more efficiently
//
template <typename ValueType>
BOOST_FORCEINLINE std::size_t popcount(ValueType value) BOOST_NOEXCEPT
{
std::size_t num = 0u;
while (value) {
num += count_table<>::table[value & ((1u<<table_width) - 1)];
value >>= table_width;
}
return num;
}
#if (((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))) \
&& (defined(__POPCNT__) || defined(__AVX__))
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned short>(unsigned short value) BOOST_NOEXCEPT
{
return static_cast<std::size_t>(__popcnt16(value));
}
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
{
return static_cast<std::size_t>(__popcnt(value));
}
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned __int64>(unsigned __int64 value) BOOST_NOEXCEPT
{
#if defined(_M_X64)
return static_cast<std::size_t>(__popcnt64(value));
#else
return static_cast<std::size_t>(__popcnt(static_cast< unsigned int >(value))) + static_cast<std::size_t>(__popcnt(static_cast< unsigned int >(value >> 32)));
#endif
}
#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__))
// Note: gcc builtins are implemented by compiler runtime when the target CPU may not support the necessary instructions
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned short>(unsigned short value) BOOST_NOEXCEPT
{
return static_cast<unsigned int>(__builtin_popcount(static_cast<unsigned int>(value)));
}
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned int>(unsigned int value) BOOST_NOEXCEPT
{
return static_cast<unsigned int>(__builtin_popcount(value));
}
template <>
BOOST_FORCEINLINE std::size_t popcount<unsigned long>(unsigned long value) BOOST_NOEXCEPT
{
return static_cast<unsigned int>(__builtin_popcountl(value));
}
template <>
BOOST_FORCEINLINE std::size_t popcount<boost::ulong_long_type>(boost::ulong_long_type value) BOOST_NOEXCEPT
{
return static_cast<unsigned int>(__builtin_popcountll(value));
}
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
// 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 num1 = 0u, num2 = 0u;
while (length >= 2u) {
num1 += popcount<ValueType>(*first);
++first;
num2 += popcount<ValueType>(*first);
++first;
length -= 2u;
}
BOOST_dynamic_bitset_is_numeric( signed char );
BOOST_dynamic_bitset_is_numeric( short );
BOOST_dynamic_bitset_is_numeric( int );
BOOST_dynamic_bitset_is_numeric( long );
if (length > 0u)
num1 += popcount<ValueType>(*first);
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 );
return num1 + num2;
}
// 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>*)
{
if (length > 0u) {
const byte_type* p = object_representation(&*first);
length *= sizeof(*first);
return do_count(p, length, static_cast<byte_type>(0u),
static_cast< value_to_type<access_by_blocks>* >(0));
}
return 0u;
}
// -------------------------------------------------------
// 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);
#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
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);
// 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
} // 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, 2025 Gennaro Prota
//
@@ -15,25 +15,22 @@
#define BOOST_LOWEST_BIT_HPP_GP_20030301
#include "boost/assert.hpp"
#include "boost/integer/integer_log2.hpp"
#include "boost/core/bit.hpp"
#include <type_traits>
namespace boost {
namespace detail {
template <typename T>
int lowest_bit(T x) {
template< typename T >
int
lowest_bit( T x )
{
BOOST_ASSERT( x >= 1 );
BOOST_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) ) );
}
return boost::core::countr_zero( static_cast< typename std::make_unsigned< T >::type >( x ) );
}
}
}
#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

@@ -16,31 +16,34 @@
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 & boost::make_nvp("m_num_bits", bs.m_num_bits)
& boost::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 AllocatorOrContainer = 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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,370 +14,370 @@
#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, typename AllocatorOrContainer = std::allocator< Block > >
void
run_test_cases()
{
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, AllocatorOrContainer > 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);
bitset_type lhs, rhs;
Tests::and_assignment( lhs, rhs );
}
{
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_left_assignment(b, pos);
bitset_type 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);
bitset_type 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);
{
bitset_type lhs( long_string.size(), 1 ), rhs( long_string );
Tests::and_assignment( lhs, rhs );
}
//=====================================================================
// Test operator |=
{
bitset_type lhs, rhs;
Tests::or_assignment( lhs, rhs );
}
{
bitset_type lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::or_assignment( lhs, rhs );
}
{
bitset_type lhs( long_string.size(), 0 ), rhs( long_string );
Tests::or_assignment( lhs, rhs );
}
{
bitset_type lhs( long_string.size(), 1 ), rhs( long_string );
Tests::or_assignment( lhs, rhs );
}
//=====================================================================
// Test operator^=
{
bitset_type lhs, rhs;
Tests::xor_assignment( lhs, rhs );
}
{
bitset_type lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::xor_assignment( lhs, rhs );
}
{
bitset_type lhs( std::string( "0" ) ), rhs( std::string( "1" ) );
Tests::xor_assignment( lhs, rhs );
}
{
bitset_type lhs( long_string ), rhs( long_string );
Tests::xor_assignment( lhs, rhs );
}
//=====================================================================
// Test operator-=
{
bitset_type lhs, rhs;
Tests::sub_assignment( lhs, rhs );
}
{
bitset_type lhs( std::string( "1" ) ), rhs( std::string( "0" ) );
Tests::sub_assignment( lhs, rhs );
}
{
bitset_type lhs( std::string( "0" ) ), rhs( std::string( "1" ) );
Tests::sub_assignment( lhs, rhs );
}
{
bitset_type lhs( long_string ), rhs( long_string );
Tests::sub_assignment( lhs, rhs );
}
//=====================================================================
// Test operator<<=
{ // case pos == 0
std::size_t pos = 0;
{
bitset_type b;
Tests::shift_left_assignment( b, pos );
}
{
bitset_type b( std::string( "1010" ) );
Tests::shift_left_assignment( b, pos );
}
{
bitset_type 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;
bitset_type 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;
bitset_type b( long_string );
Tests::shift_left_assignment( b, pos );
}
{ // case pos >= n
std::size_t pos = long_string.size();
bitset_type b( long_string );
Tests::shift_left_assignment( b, pos );
}
//=====================================================================
// Test operator>>=
{ // case pos == 0
std::size_t pos = 0;
{
bitset_type b;
Tests::shift_right_assignment( b, pos );
}
{
bitset_type b( std::string( "1010" ) );
Tests::shift_right_assignment( b, pos );
}
{
bitset_type 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;
bitset_type 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;
bitset_type b( long_string );
Tests::shift_right_assignment( b, pos );
}
{ // case pos >= n
std::size_t pos = long_string.size();
bitset_type b( long_string );
Tests::shift_right_assignment( b, pos );
}
//=====================================================================
// test b.set()
{
bitset_type b;
Tests::set_all( b );
}
{
bitset_type b( std::string( "0" ) );
Tests::set_all( b );
}
{
bitset_type b( long_string );
Tests::set_all( b );
}
//=====================================================================
// Test b.set(pos)
{ // case pos >= b.size()
bitset_type b;
Tests::set_one( b, 0, true );
Tests::set_one( b, 0, false );
}
{ // case pos < b.size()
bitset_type b( std::string( "0" ) );
Tests::set_one( b, 0, true );
Tests::set_one( b, 0, false );
}
{ // case pos == b.size() / 2
bitset_type 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
bitset_type b( std::string( "0" ) );
Tests::set_segment( b, 0, 1, true );
Tests::set_segment( b, 0, 1, false );
}
{ // case fill the whole set
bitset_type 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
bitset_type 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
bitset_type b( long_string );
Tests::set_segment( b, bitset_type::bits_per_block / 2, b.size() - bitset_type::bits_per_block, true );
Tests::set_segment( b, bitset_type::bits_per_block / 2, b.size() - bitset_type::bits_per_block, false );
}
{ // case pos = 1, len = size - 2
bitset_type 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
bitset_type b( long_string );
Tests::set_segment( b, 3, 7, true );
Tests::set_segment( b, 3, 7, false );
}
//=====================================================================
// Test b.reset()
{
bitset_type b;
Tests::reset_all( b );
}
{
bitset_type b( std::string( "0" ) );
Tests::reset_all( b );
}
{
bitset_type b( long_string );
Tests::reset_all( b );
}
//=====================================================================
// Test b.reset(pos)
{ // case pos >= b.size()
bitset_type b;
Tests::reset_one( b, 0 );
}
{ // case pos < b.size()
bitset_type b( std::string( "0" ) );
Tests::reset_one( b, 0 );
}
{ // case pos == b.size() / 2
bitset_type b( long_string );
Tests::reset_one( b, long_string.size() / 2 );
}
//=====================================================================
// Test b.reset(pos, len)
{ // case size is 1
bitset_type b( std::string( "0" ) );
Tests::reset_segment( b, 0, 1 );
}
{ // case fill the whole set
bitset_type b( long_string );
Tests::reset_segment( b, 0, b.size() );
}
{ // case pos = size / 4, len = size / 2
bitset_type b( long_string );
Tests::reset_segment( b, b.size() / 4, b.size() / 2 );
}
{ // case pos = block_size / 2, len = size - block_size
bitset_type b( long_string );
Tests::reset_segment( b, bitset_type::bits_per_block / 2, b.size() - bitset_type::bits_per_block );
}
{ // case pos = 1, len = size - 2
bitset_type b( long_string );
Tests::reset_segment( b, 1, b.size() - 2 );
}
{ // case pos = 3, len = 7
bitset_type b( long_string );
Tests::reset_segment( b, 3, 7 );
}
//=====================================================================
// Test ~b
{
bitset_type b;
Tests::operator_flip( b );
}
{
bitset_type b( std::string( "1" ) );
Tests::operator_flip( b );
}
{
bitset_type b( long_string );
Tests::operator_flip( b );
}
//=====================================================================
// Test b.flip()
{
bitset_type b;
Tests::flip_all( b );
}
{
bitset_type b( std::string( "1" ) );
Tests::flip_all( b );
}
{
bitset_type b( long_string );
Tests::flip_all( b );
}
//=====================================================================
// Test b.flip(pos)
{ // case pos >= b.size()
bitset_type b;
Tests::flip_one( b, 0 );
}
{ // case pos < b.size()
bitset_type b( std::string( "0" ) );
Tests::flip_one( b, 0 );
}
{ // case pos == b.size() / 2
bitset_type b( long_string );
Tests::flip_one( b, long_string.size() / 2 );
}
//=====================================================================
// Test b.flip(pos, len)
{ // case size is 1
bitset_type b( std::string( "0" ) );
Tests::flip_segment( b, 0, 1 );
}
{ // case fill the whole set
bitset_type b( long_string );
Tests::flip_segment( b, 0, b.size() );
}
{ // case pos = size / 4, len = size / 2
bitset_type b( long_string );
Tests::flip_segment( b, b.size() / 4, b.size() / 2 );
}
{ // case pos = block_size / 2, len = size - block_size
bitset_type b( long_string );
Tests::flip_segment( b, bitset_type::bits_per_block / 2, b.size() - bitset_type::bits_per_block );
}
{ // case pos = 1, len = size - 2
bitset_type b( long_string );
Tests::flip_segment( b, 1, b.size() - 2 );
}
{ // case pos = 3, len = 7
bitset_type 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.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);
}
}
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
run_test_cases< unsigned char >();
run_test_cases< unsigned char, small_vector< unsigned char > >();
run_test_cases< unsigned short >();
run_test_cases< unsigned short, small_vector< unsigned short > >();
run_test_cases< unsigned int >();
run_test_cases< unsigned int, small_vector< unsigned int > >();
run_test_cases< unsigned long >();
run_test_cases< unsigned long, small_vector< unsigned long > >();
#ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type >();
run_test_cases< ::boost::ulong_long_type, small_vector< ::boost::ulong_long_type > >();
#endif
return boost::report_errors();
return boost::report_errors();
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,327 +12,305 @@
#include "boost/config.hpp"
#include "boost/config/workaround.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include <assert.h>
#include <cstddef>
#include <fstream>
#include <stdexcept>
#include <string>
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#if ! defined( BOOST_NO_STRINGSTREAM )
# include <sstream>
#endif
// 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
#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, typename AllocatorOrContainer = std::allocator< Block > >
void
run_test_cases()
{
typedef boost::dynamic_bitset< Block, AllocatorOrContainer > 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
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());
}
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 BOOST_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
{
scoped_temp_file stf;
bitset_type b(1, 255ul);
{
std::ofstream f(stf.path().string().c_str());
f << 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]);
}
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
{
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;
}
#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(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::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
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 char, small_vector< unsigned char > >();
run_test_cases< unsigned short >();
run_test_cases< unsigned short, small_vector< unsigned short > >();
run_test_cases< unsigned int >();
run_test_cases< unsigned int, small_vector< unsigned int > >();
run_test_cases< unsigned long >();
run_test_cases< unsigned long, small_vector< unsigned long > >();
#ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type >();
run_test_cases< ::boost::ulong_long_type, small_vector< ::boost::ulong_long_type > >();
#endif
return boost::report_errors();
return boost::report_errors();
}

View File

@@ -20,92 +20,94 @@
#include "boost/dynamic_bitset/serialization.hpp"
#include "boost/serialization/vector.hpp"
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#if ! defined( BOOST_NO_STRINGSTREAM )
# include <sstream>
#endif
// 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
#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
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()
{
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()
{
test_binary_archive<Block>();
test_xml_archive<Block>();
test_serialization< Block, boost::archive::binary_iarchive, boost::archive::binary_oarchive >();
}
int main()
template< typename Block >
void
test_xml_archive()
{
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
test_serialization< Block, boost::archive::xml_iarchive, boost::archive::xml_oarchive >();
}
}
template< typename Block >
void
run_test_cases()
{
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

@@ -1,10 +1,5 @@
//
// Copyright (C) 2018 James E. King III
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,17 +9,18 @@
#include "boost/core/lightweight_test.hpp"
#include "boost/dynamic_bitset.hpp"
int main(int, char*[])
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));
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();
}

View File

@@ -1,11 +1,6 @@
//
// Copyright (C) 2019 James E. King III
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// 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)
@@ -16,32 +11,33 @@
#include "boost/dynamic_bitset.hpp"
#include <set>
int main(int, char*[])
int
main( int, char *[] )
{
typedef boost::dynamic_bitset<unsigned long> bitset_type;
const std::string long_string =
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);
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));
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);
BOOST_TEST_EQ( results.size(), 5 );
return boost::report_errors();
}

View File

@@ -1,10 +1,5 @@
//
// Copyright (C) 2018 James E. King III
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,14 +10,15 @@
#include "boost/cstdint.hpp"
#include "boost/dynamic_bitset/detail/lowest_bit.hpp"
int main(int, char*[])
int
main( int, char *[] )
{
for (boost::int32_t i = 1; i < 32; ++i) {
BOOST_TEST_EQ(i, boost::detail::lowest_bit(1u << i));
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)));
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();
}

View File

@@ -1,39 +1,32 @@
//
// Copyright (C) 2019 James E. King III
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// 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/core/lightweight_test.hpp"
#include "boost/dynamic_bitset.hpp"
#include <functional>
#include <unordered_set>
int main(int, char*[])
int
main( int, char *[] )
{
typedef boost::dynamic_bitset<unsigned long> bitset_type;
const std::string long_string =
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);
const bitset_type zeroes( long_string.size(), 0 );
const bitset_type stuff( long_string );
const bitset_type one( long_string.size(), 1 );
std::unordered_set<bitset_type> bitsets;
bitsets.insert(zeroes);
bitsets.insert(stuff);
bitsets.insert(ones);
std::unordered_set< bitset_type > bitsets;
bitsets.insert( zeroes );
bitsets.insert( stuff );
bitsets.insert( one );
BOOST_TEST_EQ(bitsets.size(), 3);
BOOST_TEST_EQ( bitsets.size(), 3 );
return boost::report_errors();
}