Compare commits

...

86 Commits

Author SHA1 Message Date
Marshall Clow
6cb9cf71de Release 1.52.0
[SVN r81201]
2012-11-05 15:31:58 +00:00
Marshall Clow
f44fbae9ba Merge fixes to release; Fixes #5439
[SVN r72331]
2011-06-01 15:59:04 +00:00
Steven Watanabe
e6fc8e8ec9 Merge dynamic_bitset from the trunk
[SVN r67617]
2011-01-03 16:38:46 +00:00
Troy D. Straszheim
d77a2c4afa rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Troy D. Straszheim
e3a2ca7276 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Daniel James
38819630fd Merge dynamic bitset fixes for gcc 4.3.3.
Merged revisions 52879-52881,53050 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52879 | hkaiser | 2009-05-10 17:52:14 +0100 (Sun, 10 May 2009) | 1 line
  
  Applying patch fixing problem on certain patch levels for gcc.4.3.3/Ubuntu
........
  r52880 | hkaiser | 2009-05-10 17:55:07 +0100 (Sun, 10 May 2009) | 1 line
  
  Fixing the fix by taking into account __GNUC_PATCHLEVEL__ as well
........
  r52881 | hkaiser | 2009-05-10 17:59:27 +0100 (Sun, 10 May 2009) | 1 line
  
  Minor comment edit
........
  r53050 | danieljames | 2009-05-16 15:58:33 +0100 (Sat, 16 May 2009) | 13 lines
  
  Merge dynamic bitset from release.
  
  I think the recent changes in trunk and release were for the same problem. But
  I'm not sure so I've merged them together. Hopefully, the release branch might
  fix the Intel C++ errors as well.
  
  ------------------------------------------------------------------------
  r52960 | dgregor | 2009-05-13 07:11:03 +0100 (Wed, 13 May 2009) | 1 line
  
  Use enum constants rather than local variables for integral constants. Should fix dynamic_bitset failures on GCC 4.3.x
  ------------------------------------------------------------------------
........


[SVN r53259]
2009-05-25 20:26:02 +00:00
Douglas Gregor
6d0f9801f5 Use enum constants rather than local variables for integral constants. Should fix dynamic_bitset failures on GCC 4.3.x
[SVN r52960]
2009-05-13 06:11:03 +00:00
Troy D. Straszheim
b7eedd0f46 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Gennaro Prota
16ca9cbb3c dynamic_bitset: ported revisions 49433, 49586 from trunk
[SVN r50470]
2009-01-04 23:03:28 +00:00
Gennaro Prota
4efeaee302 dynamic_bitset: full (recursive) sync with trunk for libs/dynamic_bitset/
[SVN r49423]
2008-10-21 17:57:39 +00:00
Gennaro Prota
066e7dcf71 dynamic_bitset:
ported revisions 49345-49346 (roughly: workaround for VC++ <= 7.0 removal, comment and documentation improvements) from trunk

[SVN r49378]
2008-10-18 11:04:39 +00:00
Gennaro Prota
6b0d9627a8 Ported *all* my trunk changes not yet merged so far, i.e. revisions 48251-48252,48280,48290,48350,48478,48496,48663-48664,48695,48729-48730; besides dynamic_bitset, these include fixes to setup_boostbook.sh and setup_boostbook.py, and changes to config/suffix.hpp [So: the affected "elements" are: a) the two setup_boostbook scripts, config/suffix.hpp and dynamic_bitset --note: yes, the list is exhaustive: all and only]
[SVN r48773]
2008-09-14 10:46:28 +00:00
Gennaro Prota
bddf77e5a4 boost/pending/: ported revision 48251 ("integer_log2.hpp and lowest_bit.hpp, in boost/pending/: little comment cleanup (svn anchors, etc.); added a static_cast<> to silence (harmless) MSVC++ warnings") from trunk
[SVN r48353]
2008-08-24 18:16:24 +00:00
Gennaro Prota
357e434387 dynamic_bitset.hpp: (minor) removed tab characters introduced with revision 35066 on trunk
[SVN r47666]
2008-07-21 23:46:39 +00:00
Gennaro Prota
d8b2330d42 dynamic_bitset.html: Documentation: dropped all sentences of the kind "note that the expression... is equivalent to creating a temporary copy and then...". They seem to be just a sort of performance warning and carry no useful information. This fixes issue #1591.
[SVN r47328]
2008-07-11 21:21:14 +00:00
Daniel James
61702fef06 Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Boris Gubenko
6bf10f4ef0 merge change in trunk (changeset/41778) to release branch
[SVN r41959]
2007-12-10 18:51:19 +00:00
Beman Dawes
0999a9b907 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
4ae778ba4a Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
c9dcc1de64 config, detail, filesystem, system, tools, at 41278.
[SVN r41316]
2007-11-23 17:03:14 +00:00
Beman Dawes
cc9b262cb9 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
ba7ccc50ae This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Rene Rivera
3e03a8d947 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Gennaro Prota
a0d66fd920 prevented spurious Digital Mars warning
[SVN r34645]
2006-07-20 22:55:07 +00:00
Gennaro Prota
3e3d36c571 added extra parentheses to workaround Digital Mars
[SVN r34644]
2006-07-20 22:52:21 +00:00
Gennaro Prota
3be249a20e workarounded absurd Digital Mars behavior
[SVN r34643]
2006-07-20 22:50:11 +00:00
Gennaro Prota
5f1c39cb6c added copyright/license notes
[SVN r34570]
2006-07-17 02:14:22 +00:00
Gennaro Prota
7c48bf04c2 added copyright/license notes; validated (XHTML 1.0 Strict)
[SVN r34569]
2006-07-17 02:09:49 +00:00
nobody
5e260f4364 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Markus Schöpflin
896a792bec Workaround for IBM's compiler on AIX.
[SVN r32101]
2005-12-19 10:00:51 +00:00
Douglas Gregor
39f11e7cc0 Workaround for CodeWarrior 9.4/9.5, I think
[SVN r28956]
2005-05-16 14:22:35 +00:00
Aleksey Gurtovoy
b18fc5cd99 merge RC_1_32_0 fixes
[SVN r26328]
2004-11-28 03:35:12 +00:00
Aleksey Gurtovoy
c5ea9df026 c++boost.gif -> boost.png replacement
[SVN r25573]
2004-10-05 15:45:52 +00:00
John Maddock
6f1a3ed336 Added new types boost::long_long_type and boost::ulong_long_type in boost/config.hpp and applied these types in place of "long long" throughout. As a result, almost all of boost now compiles cleanly with -ansi -pedantic with gcc. Changes tested with gcc 3.3, 2.95, VC7.1 and Intel 8.
[SVN r24899]
2004-09-04 10:34:49 +00:00
Rene Rivera
e85ab3cb63 Add workaround for CW8 when it compiles reset(), as it generates invalid code otherwise.
[SVN r24319]
2004-08-06 06:56:13 +00:00
Rene Rivera
c23e3f28dc Prevent "possibly unwanted ;" warning.
[SVN r24318]
2004-08-06 06:54:07 +00:00
Douglas Gregor
f4eefb6abb dynamic_bitset.hpp: Split the string constructor, which causes problems on the
msvc-stlport toolset, into two separate constructors to avoid the npos issue.


[SVN r24179]
2004-07-30 04:41:57 +00:00
Douglas Gregor
f28eec4a37 Converted to Boost Software License, Version 1.0
[SVN r24055]
2004-07-26 00:32:12 +00:00
Gennaro Prota
e2529a0423 settled macros to cope with the absence of std::locale on some platforms/configurations
[SVN r23886]
2004-07-21 09:23:17 +00:00
Vladimir Prus
0ff409e7d6 More V2 Jamfile tweaks.
[SVN r23764]
2004-07-19 07:12:45 +00:00
Gennaro Prota
912ab0576e use BOOST_WORKAROUND for Codewarrior workarounds
[SVN r23207]
2004-06-27 08:54:02 +00:00
Gennaro Prota
abd8bc3795 Fix for Codewarrior 8.3 for Windows. Suggested by Howard Hinnant.
[SVN r23198]
2004-06-26 08:48:53 +00:00
Gennaro Prota
42922140ed typo
[SVN r23127]
2004-06-20 09:33:03 +00:00
Gennaro Prota
fe0c5c0563 new Codewarrior workaround
[SVN r23124]
2004-06-19 08:32:31 +00:00
Gennaro Prota
f46a423bbe restored version 1.6 (MW attempts failed)
[SVN r23123]
2004-06-19 08:27:45 +00:00
Gennaro Prota
6d8300e094 attempt to fix another CW 8.3 error :(
[SVN r23094]
2004-06-13 07:48:46 +00:00
Gennaro Prota
8c5ab9dcca CW 8.3 fix suggested by Howard
[SVN r23092]
2004-06-12 08:18:26 +00:00
Gennaro Prota
7d3869d208 use boost::detail::distance instead of std::distance
[SVN r23025]
2004-06-05 08:45:02 +00:00
Gennaro Prota
4fe6bbdbed local array numbers[] made static - this is an attempt to fix a CW 8.3 error
[SVN r22996]
2004-06-02 08:30:53 +00:00
Gennaro Prota
31f06cc395 exclude wchar_t tests when BOOST_NO_STD_LOCALE is defined
[SVN r22973]
2004-05-30 09:42:44 +00:00
Gennaro Prota
f4073fc6aa - added a missing #include (climits)
- extended usage of BOOST_BITSET_CHAR to accomodate libraries with no locale support (MWCW with _MSL_NO_LOCALE)
- untabified


[SVN r22972]
2004-05-30 09:40:25 +00:00
Gennaro Prota
f61de66d04 removed some superfluous spaces and added workaround for VC6's Dinkum
[SVN r22833]
2004-05-16 08:43:38 +00:00
Gennaro Prota
c688bf1763 changed workaround for gcc bug nr. 8419
[SVN r22771]
2004-05-09 09:21:33 +00:00
Gennaro Prota
0c613d24c4 - workaround for Borland bug
- untabified


[SVN r22769]
2004-05-09 08:03:21 +00:00
Gennaro Prota
e6ca3c67c4 use division by 2 instead of >>=1, because Borland C++ yields sometimes an access violation when shifting with Block = unsigned long long
[SVN r22768]
2004-05-09 07:48:12 +00:00
Gennaro Prota
c1d95c8d3e Added URI of the DTD in the <!DOCTYPE> tag
[SVN r22764]
2004-05-08 08:27:59 +00:00
Gennaro Prota
5cdfb675be removed superfluous spaces
[SVN r22704]
2004-04-25 09:04:36 +00:00
Gennaro Prota
3af18952b3 just aligned a backslash
[SVN r22703]
2004-04-25 09:03:10 +00:00
Gennaro Prota
a1cc5de6eb removed #undef for BOOST_OLD_IOSTREAMS
[SVN r22702]
2004-04-25 08:54:14 +00:00
Gennaro Prota
48f9b61f3d no message
[SVN r22700]
2004-04-25 08:30:00 +00:00
Gennaro Prota
9015fe1e59 removed the 3 examples and the "timing_tests" file (this way we can use bjam's subinclude feature from boost-root/status/Jamfile without also running examples etc. with the regression tests)
[SVN r22699]
2004-04-25 08:29:17 +00:00
Gennaro Prota
ebcb04e23b Jamfile for examples and 'timing_tests' - doesn't run with the regression tests, of course
[SVN r22698]
2004-04-25 08:24:50 +00:00
Gennaro Prota
ddc4d80d4b moved here from the parent directory
[SVN r22697]
2004-04-25 08:21:42 +00:00
Gennaro Prota
c5f0c1610f new license reference
[SVN r22696]
2004-04-25 08:15:26 +00:00
Gennaro Prota
3942289151 the examples - moved here so that they can have an independent Jamfile that doesn't trigger together with the regression tests
[SVN r22695]
2004-04-25 08:09:46 +00:00
Gennaro Prota
29f03d2456 removed (will go into the example/ subdirectory)
[SVN r22694]
2004-04-25 08:05:11 +00:00
Gennaro Prota
7e9eaaa25f removed definition of BOOST_OLD_IOSTREAMS (it's now in the dynamic_bitset config file)
[SVN r22693]
2004-04-25 07:45:09 +00:00
Gennaro Prota
c516fe3cb8 test functions call to_string, to_block_range, etc., so let's include "boost/dynamic_bitset.hpp" (see regression logs for gcc 3.4 on Linux)
[SVN r22692]
2004-04-24 09:04:01 +00:00
Gennaro Prota
37fd8373e8 removed const qualification on test_file_name()'s return type
[SVN r22691]
2004-04-24 08:55:08 +00:00
Gennaro Prota
0d8327315c moved more config stuff to here
[SVN r22690]
2004-04-24 08:48:36 +00:00
Gennaro Prota
99035b25ac removed config stuff
[SVN r22689]
2004-04-24 08:48:03 +00:00
Gennaro Prota
7068fe4b24 removed make_non_const() workaround, now useless
[SVN r22688]
2004-04-24 08:38:55 +00:00
Gennaro Prota
9ce38213e4 config stuff
[SVN r22687]
2004-04-24 08:36:46 +00:00
Gennaro Prota
e03aea94d9 moved config stuff to its own file and changed workaround for gcc bug 8419, as the former workaround gave problems with some compilers (e.g. VACPP for AIX)
[SVN r22686]
2004-04-24 08:35:42 +00:00
Gennaro Prota
8397bc3326 - removed dependency on test_exec_monitor
- added dyn_bitset_unit_tests4


[SVN r22652]
2004-04-18 09:24:05 +00:00
Gennaro Prota
760839ff10 new file (needed by dynamic_bitset)
[SVN r22651]
2004-04-18 09:15:08 +00:00
Gennaro Prota
16a25f7f10 moved from the sandbox
[SVN r22650]
2004-04-18 09:14:20 +00:00
Gennaro Prota
d35b2d1117 new tests (from the sandbox)
[SVN r22649]
2004-04-18 09:13:06 +00:00
Gennaro Prota
6e9450562e new version (from the sandbox)
[SVN r22648]
2004-04-18 09:11:17 +00:00
Gennaro Prota
e445e12e06 new version (the actual code, from the sandbox, is in dynamic_bitset/dynamic_bitset.hpp)
[SVN r22647]
2004-04-18 09:07:24 +00:00
Eric Niebler
f66792a57d remove minmax hack from win32.hpp and fix all places that could be affected by the minmax macros
[SVN r22394]
2004-02-26 18:27:02 +00:00
Jens Maurer
702e7dd26b remove unused variable
[SVN r18997]
2003-07-09 19:41:40 +00:00
Gennaro Prota
d878395ca6 small comment fixes again
[SVN r18279]
2003-04-19 14:11:14 +00:00
Gennaro Prota
c4a81fc3e8 shortened comments
[SVN r18278]
2003-04-19 11:47:17 +00:00
Gennaro Prota
588891f0a1 minor comment fixes
[SVN r18036]
2003-03-20 18:22:31 +00:00
Gennaro Prota
fd8ccde0b4 overall cleanup
[SVN r18035]
2003-03-20 18:08:42 +00:00
24 changed files with 5105 additions and 3023 deletions

40
Jamfile
View File

@@ -1,40 +0,0 @@
subproject libs/dynamic_bitset ;
unit-test dyn_bitset_unit_tests1
: dyn_bitset_unit_tests1.cpp
<lib>../test/build/test_exec_monitor
: <include>$(BOOST_ROOT)
;
unit-test dyn_bitset_unit_tests2
: dyn_bitset_unit_tests2.cpp
<lib>../test/build/test_exec_monitor
: <include>$(BOOST_ROOT)
;
unit-test dyn_bitset_unit_tests3
: dyn_bitset_unit_tests3.cpp
<lib>../test/build/test_exec_monitor
: <include>$(BOOST_ROOT)
;
exe timing_tests
: timing_tests.cpp
: <include>$(BOOST_ROOT)
;
exe example1
: example1.cpp
: <include>$(BOOST_ROOT)
;
exe example2
: example2.cpp
: <include>$(BOOST_ROOT)
;
exe example3
: example3.cpp
: <include>$(BOOST_ROOT)
;

14
Jamfile.v2 Normal file
View File

@@ -0,0 +1,14 @@
#
# Copyright Vladimir Prus 2004
#
# 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)
test-suite dynamic_bitset :
[ run dyn_bitset_unit_tests1.cpp ]
[ run dyn_bitset_unit_tests2.cpp ]
[ run dyn_bitset_unit_tests3.cpp ]
[ run dyn_bitset_unit_tests4.cpp ]
;

View File

@@ -1,118 +1,255 @@
// (C) Copyright Jeremy Siek 2001.
// 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.
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006, 2008 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)
//
// -----------------------------------------------------------
#ifndef BOOST_BITSET_TEST_HPP_GP_20040319
#define BOOST_BITSET_TEST_HPP_GP_20040319
#include "boost/config.hpp"
#if !defined (BOOST_NO_STD_LOCALE)
# include <locale>
#endif
#include <vector>
#include <fstream> // used for operator<<
#include <string> // for (basic_string and) getline()
#include <algorithm> // for std::min
#include <fstream>
#include <boost/test/test_tools.hpp>
#include <assert.h> // <cassert> is sometimes macro-guarded :-(
#include "boost/limits.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/test/minimal.hpp"
// Extract the bit at position n from num.
template <typename Block>
inline bool nth_bit(Block num, std::size_t n)
{
// Move the nth bit to position 0 and then clear all other bits.
return (num >> n) & 1;
#ifdef __BORLANDC__
// Borland deduces Block as a const qualified type,
// and thus finds numeric_limits<Block> to be zero :(
// (though not directly relevant here, see also
// lib issue 559)
int block_width = sizeof(Block) * CHAR_BIT;
#else
int block_width = std::numeric_limits<Block>::digits;
#endif
assert(n < (std::size_t) block_width);
return (num >> n) & 1;
}
inline unsigned long max_num(std::size_t num_bits)
// A long, 'irregular', string useful for various tests
std::string get_long_string()
{
using namespace std; // for std::pow, VC++ workaround -JGS
return (unsigned long)(pow((double)2, (double)num_bits));
const char * const p =
// 6 5 4 3 2 1
// 3210987654321098765432109876543210987654321098765432109876543210
"1110011100011110000011110000011111110000000000000110101110000000"
"1010101000011100011101010111110000101011111000001111100011100011"
"0000000110000001000000111100000111100010101111111000000011100011"
"1111111111111111111111111111111111111111111111111111111111111100"
"1000001100000001111111111111110000000011111000111100001010100000"
"101000111100011010101110011011000000010";
return std::string(p);
}
const char * test_file_name()
{
return "boost_dynamic_bitset_tests";
}
#if defined BOOST_OLD_IOSTREAMS || defined BOOST_NO_STD_LOCALE
template <typename Stream>
bool is_one_or_zero(const Stream & /*s*/, char c)
{
return c == '1' || c == '0';
}
template <typename Stream>
bool is_white_space(const Stream & /*s*/, char c)
{
return std::isspace(c);
}
#else
template <typename Stream, typename Ch>
bool is_one_or_zero(const Stream& s, Ch c)
{
typedef typename Stream::traits_type Tr;
const Ch zero = s.widen('0');
const Ch one = s.widen('1');
return Tr::eq(c, one) || Tr::eq(c, zero);
}
template <typename Stream, typename Ch>
bool is_white_space(const Stream & s, Ch c)
{
// NOTE: the using directive is to satisfy Borland 5.6.4
// with its own library (STLport), which doesn't
// like std::isspace(c, loc)
using namespace std;
return isspace(c, s.getloc());
}
#endif // defined BOOST_OLD_IOSTREAMS
template <typename Stream>
bool has_flags(const Stream& s, std::ios::iostate flags)
{
return (s.rdstate() & flags) != std::ios::goodbit;
}
// constructors
// default (can't do this generically)
// from unsigned long
template <typename Bitset>
struct bitset_test {
static void from_unsigned_long(Bitset b, unsigned long num)
typedef typename Bitset::block_type Block;
BOOST_STATIC_CONSTANT(int, bits_per_block = Bitset::bits_per_block);
// from unsigned long
//
// Note: this is templatized so that we check that the do-the-right-thing
// constructor dispatch is working correctly.
//
template <typename NumBits, typename Value>
static void from_unsigned_long(NumBits num_bits, Value num)
{
// initializes the first M bit position to the cooresponding bit
// values in val. M is the smaller of N and the value CHAR_BIT *
// sizeof(unsigned long)
// An object of size sz = num_bits is constructed:
// - the first m bit positions are initialized to the corresponding
// bit values in num (m being the smaller of sz and ulong_width)
//
// - any remaining bit positions are initialized to zero
//
// missing from the std?
// if M < N then the remaining bit positions are initialized to zero
Bitset b(num_bits, num);
std::size_t N = b.size();
std::size_t M = std::min(N, CHAR_BIT * sizeof(unsigned long));
std::size_t I;
for (I = 0; I < M; ++I)
BOOST_CHECK(b[I] == nth_bit(num, I));
for (; I < N; ++I)
BOOST_CHECK(b[I] == 0);
// OK, we can now cast to size_type
typedef typename Bitset::size_type size_type;
const size_type sz = static_cast<size_type>(num_bits);
BOOST_CHECK(b.size() == sz);
const std::size_t ulong_width = std::numeric_limits<unsigned long>::digits;
size_type m = sz;
if (ulong_width < sz)
m = ulong_width;
size_type i = 0;
for ( ; i < m; ++i)
BOOST_CHECK(b.test(i) == nth_bit(static_cast<unsigned long>(num), i));
for ( ; i < sz; ++i)
BOOST_CHECK(b.test(i) == 0);
}
// from string
static void from_string(const std::string& str, std::size_t pos,
std::size_t n)
// from string
//
// Note: The corresponding function in dynamic_bitset (constructor
// from a string) has several default arguments. Actually we don't
// test the correct working of those defaults here (except for the
// default of num_bits). I'm not sure what to do in this regard.
//
// Note2: the default argument expression for num_bits doesn't use
// static_cast, to avoid a gcc 2.95.3 'sorry, not implemented'
//
template <typename Ch, typename Tr, typename Al>
static void from_string(const std::basic_string<Ch, Tr, Al>& str,
std::size_t pos,
std::size_t max_char,
std::size_t num_bits = (std::size_t)(-1))
{
if (pos > str.size()) {
// Not in range, doesn't satisfy precondition.
} else {
std::size_t rlen = std::min(n, str.size() - pos);
// Throws invalid_argument if any of the rlen characters in str
// beginning at position pos is other than 0 or 1.
bool any_non_zero_or_one = false;
for (std::size_t i = pos; i < pos + rlen; ++i)
if (! (str[i] == '0' || str[i] == '1'))
any_non_zero_or_one = true;
if (any_non_zero_or_one) {
// Input does not satisfy precondition.
} else {
// Construct an object, initializing the first M bit position to
// values determined from the corresponding characters in the
// str. M is the smaller of N and rlen. Character position pos
// + M - 1 corresponds to bit position zero. Subsequent
// decreasing character position correspond to increasing bit
// positions.
std::size_t rlen = (std::min)(max_char, str.size() - pos);
Bitset b(str, pos, n);
std::size_t N = b.size();
std::size_t M = std::min(N, rlen);
std::size_t j;
for (j = 0; j < M; ++j)
BOOST_CHECK(b[j] == (str[pos + M - 1 - j] == '1'));
// If M < N, remaining bit positions are initialize to zero
for (; j < N; ++j)
// The resulting size N of the bitset is num_bits, if
// that is different from the default arg, rlen otherwise.
// Put M = the smaller of N and rlen, then character
// position pos + M - 1 corresponds to bit position zero.
// Subsequent decreasing character positions correspond to
// increasing bit positions.
const bool size_upon_string = num_bits == (std::size_t)(-1);
Bitset b = size_upon_string ?
Bitset(str, pos, max_char)
: Bitset(str, pos, max_char, num_bits);
const std::size_t actual_size = size_upon_string? rlen : num_bits;
BOOST_CHECK(b.size() == actual_size);
std::size_t m = (std::min)(num_bits, rlen);
std::size_t j;
for (j = 0; j < m; ++j)
BOOST_CHECK(b[j] == (str[pos + m - 1 - j] == '1'));
// If M < N, remaining bit positions are zero
for (; j < actual_size; ++j)
BOOST_CHECK(b[j] == 0);
}
static void to_block_range(const Bitset & b /*, BlockOutputIterator result*/)
{
typedef typename Bitset::size_type size_type;
Block sentinel = 0xF0;
int s = 8; // number of sentinels (must be *even*)
int offset = s/2;
std::vector<Block> v(b.num_blocks() + s, sentinel);
boost::to_block_range(b, v.begin() + offset);
assert(v.size() >= (size_type)s && (s >= 2) && (s % 2 == 0));
// check sentinels at both ends
for(int i = 0; i < s/2; ++i) {
BOOST_CHECK(v[i] == sentinel);
BOOST_CHECK(v[v.size()-1-i] == sentinel);
}
typename std::vector<Block>::const_iterator p = v.begin() + offset;
for(size_type n = 0; n < b.num_blocks(); ++n, ++p) {
typename Bitset::block_width_type i = 0;
for(; i < bits_per_block; ++i) {
size_type bit = n * bits_per_block + i;
BOOST_CHECK(nth_bit(*p, i) == (bit < b.size()? b[bit] : 0));
}
}
}
typedef typename Bitset::block_type Block;
// TODO from_block_range (below) should be splitted
// PRE: std::equal(first1, last1, first2) == true
static void from_block_range(std::vector<Block> blocks)
static void from_block_range(const std::vector<Block>& blocks)
{
{
{ // test constructor from block range
Bitset bset(blocks.begin(), blocks.end());
std::size_t n = blocks.size();
for (std::size_t b = 0; b < n; ++b) {
for (std::size_t i = 0; i < sizeof(Block) * CHAR_BIT; ++i) {
std::size_t bit = b * sizeof(Block) * CHAR_BIT + i;
typename Bitset::block_width_type i = 0;
for (; i < bits_per_block; ++i) {
std::size_t bit = b * bits_per_block + i;
BOOST_CHECK(bset[bit] == nth_bit(blocks[b], i));
}
}
BOOST_CHECK(bset.size() == n * bits_per_block);
}
{
Bitset bset(blocks.size() * sizeof(Block) * CHAR_BIT);
{ // test boost::from_block_range
const typename Bitset::size_type n = blocks.size();
Bitset bset(n * bits_per_block);
boost::from_block_range(blocks.begin(), blocks.end(), bset);
std::size_t n = blocks.size();
for (std::size_t b = 0; b < n; ++b) {
for (std::size_t i = 0; i < sizeof(Block) * CHAR_BIT; ++i) {
std::size_t bit = b * sizeof(Block) * CHAR_BIT + i;
typename Bitset::block_width_type i = 0;
for (; i < bits_per_block; ++i) {
std::size_t bit = b * bits_per_block + i;
BOOST_CHECK(bset[bit] == nth_bit(blocks[b], i));
}
}
BOOST_CHECK(n <= bset.num_blocks());
}
}
@@ -136,7 +273,7 @@ struct bitset_test {
Bitset b(lhs);
b = rhs;
BOOST_CHECK(b == rhs);
// Changes to the copy do not affect the original
if (b.size() > 0) {
std::size_t pos = b.size() / 2;
@@ -145,6 +282,33 @@ struct bitset_test {
}
}
static void swap(const Bitset& lhs, const Bitset& rhs)
{
// bitsets must be swapped
Bitset copy1(lhs);
Bitset copy2(rhs);
copy1.swap(copy2);
BOOST_CHECK(copy1 == rhs);
BOOST_CHECK(copy2 == lhs);
// references must be stable under a swap
for(typename Bitset::size_type i = 0; i < lhs.size(); ++i) {
Bitset b1(lhs);
Bitset b2(rhs);
typename Bitset::reference ref = b1[i];
bool x = ref;
if (i < b2.size())
b2[i] = !x; // make sure b2[i] is different
b1.swap(b2);
BOOST_CHECK(b2[i] == x); // now it must be equal..
b2.flip(i);
BOOST_CHECK(ref == b2[i]); // .. and ref must be into b2
BOOST_CHECK(ref == !x);
}
}
static void resize(const Bitset& lhs)
{
Bitset b(lhs);
@@ -183,7 +347,7 @@ struct bitset_test {
BOOST_CHECK(b[b.size() - 1] == true);
for (std::size_t i = 0; i < lhs.size(); ++i)
BOOST_CHECK(b[i] == lhs[i]);
b.push_back(false);
BOOST_CHECK(b.size() == lhs.size() + 2);
BOOST_CHECK(b[b.size() - 1] == false);
@@ -197,16 +361,16 @@ struct bitset_test {
Bitset b(lhs);
Block value(128);
b.append(value);
BOOST_CHECK(b.size() == lhs.size() + Bitset::bits_per_block);
for (std::size_t i = 0; i < Bitset::bits_per_block; ++i)
BOOST_CHECK(b.size() == lhs.size() + bits_per_block);
for (typename Bitset::block_width_type i = 0; i < bits_per_block; ++i)
BOOST_CHECK(b[lhs.size() + i] == bool((value >> i) & 1));
}
static void append_block_range(const Bitset& lhs, std::vector<Block> blocks)
static void append_block_range(const Bitset& lhs, const std::vector<Block>& blocks)
{
Bitset b(lhs), c(lhs);
b.append(blocks.begin(), blocks.end());
for (typename std::vector<Block>::iterator i = blocks.begin();
for (typename std::vector<Block>::const_iterator i = blocks.begin();
i != blocks.end(); ++i)
c.append(*i);
BOOST_CHECK(b == c);
@@ -293,7 +457,7 @@ struct bitset_test {
Bitset lhs(b);
Bitset prev(lhs);
lhs |= rhs;
// Sets each bit in lhs for which the corresponding bit in rhs is set, and
// Sets each bit in lhs for which the corresponding bit in rhs is set, and
// leaves all other bits unchanged.
for (std::size_t I = 0; I < lhs.size(); ++I)
if (rhs[I] == 1)
@@ -305,7 +469,7 @@ struct bitset_test {
// PRE: b.size() == rhs.size()
static void xor_assignment(const Bitset& b, const Bitset& rhs)
{
Bitset lhs(b);
Bitset lhs(b);
Bitset prev(lhs);
lhs ^= rhs;
// Flips each bit in lhs for which the corresponding bit in rhs is set,
@@ -320,7 +484,7 @@ struct bitset_test {
// PRE: b.size() == rhs.size()
static void sub_assignment(const Bitset& b, const Bitset& rhs)
{
Bitset lhs(b);
Bitset lhs(b);
Bitset prev(lhs);
lhs -= rhs;
// Resets each bit in lhs for which the corresponding bit in rhs is set,
@@ -334,12 +498,12 @@ struct bitset_test {
static void shift_left_assignment(const Bitset& b, std::size_t pos)
{
Bitset lhs(b);
Bitset lhs(b);
Bitset prev(lhs);
lhs <<= pos;
// Replaces each bit at position I in lhs with the following value:
// - If I < pos, the new value is zero
// - If I >= pos, the new value is the previous value of the bit at
// - If I >= pos, the new value is the previous value of the bit at
// position I - pos
for (std::size_t I = 0; I < lhs.size(); ++I)
if (I < pos)
@@ -355,7 +519,7 @@ struct bitset_test {
lhs >>= pos;
// Replaces each bit at position I in lhs with the following value:
// - If pos >= N - I, the new value is zero
// - If pos < N - I, the new value is the previous value of the bit at
// - If pos < N - I, the new value is the previous value of the bit at
// position I + pos
std::size_t N = lhs.size();
for (std::size_t I = 0; I < N; ++I)
@@ -434,7 +598,7 @@ struct bitset_test {
std::size_t N = lhs.size();
Bitset prev(lhs);
lhs.flip();
// Toggles all the bits in lhs
// Toggles all the bits in lhs
for (std::size_t I = 0; I < N; ++I)
BOOST_CHECK(lhs[I] == !prev[I]);
}
@@ -458,58 +622,66 @@ struct bitset_test {
}
}
// empty
static void empty(const Bitset& b)
{
BOOST_CHECK(b.empty() == (b.size() == 0));
}
// to_ulong()
static void to_ulong(const Bitset& lhs)
{
std::size_t N = lhs.size();
std::size_t n = CHAR_BIT * sizeof(unsigned long);
typedef unsigned long result_type;
std::size_t n = std::numeric_limits<result_type>::digits;
std::size_t sz = lhs.size();
bool will_overflow = false;
for (std::size_t I = n; I < N; ++I)
if (lhs[I] != 0)
for (std::size_t i = n; i < sz; ++i) {
if (lhs.test(i) != 0) {
will_overflow = true;
break;
}
}
if (will_overflow) {
try {
(void)lhs.to_ulong();
BOOST_CHECK(false); // It should have thrown and exception
} catch (std::overflow_error) {
BOOST_CHECK(false); // It should have thrown an exception
} catch (std::overflow_error & ex) {
// Good!
BOOST_CHECK(!!ex.what());
} catch (...) {
BOOST_CHECK(false); // threw the wrong exception
}
} else {
unsigned long num = lhs.to_ulong();
// Make sure the number is right
for (std::size_t I = 0; I < N; ++I)
BOOST_CHECK(lhs[I] == nth_bit(num, I));
result_type num = lhs.to_ulong();
// Be sure the number is right
if (sz == 0)
BOOST_CHECK(num == 0);
else {
for (std::size_t i = 0; i < sz; ++i)
BOOST_CHECK(lhs[i] == (i < n ? nth_bit(num, i) : 0));
}
}
}
// to_string()
static void to_string(const Bitset& b)
{
// Construct a string object of the appropriate type and initializes
// it to a string of length N characters. Each character is determined
// by the value of its corresponding bit position in b. Character
// position N - 1 corresponds to bit position zero. Sebsequent
// decreasing character positions correspond to increasing bit
// positions. Bit value zero becomes the charactet 0, bit value one
// becomes the character 1.
std::string str;
boost::to_string(b, str);
std::size_t N = b.size();
BOOST_CHECK(str.size() == b.size());
for (std::size_t I = 0; I < b.size(); ++I)
BOOST_CHECK(b[I] == 0 ? (str[N - 1 - I] == '0') : (str[N - 1 - I] == '1'));
for (std::size_t i = 0; i < b.size(); ++i)
BOOST_CHECK(str[b.size() - 1 - i] ==(b.test(i)? '1':'0'));
}
static void count(const Bitset& b)
{
std::size_t c = b.count();
std::size_t c_real = 0;
for (std::size_t I = 0; I < b.size(); ++I)
if (b[I])
++c_real;
BOOST_CHECK(c == c_real);
std::size_t actual = 0;
for (std::size_t i = 0; i < b.size(); ++i)
if (b[i])
++actual;
BOOST_CHECK(c == actual);
}
static void size(const Bitset& b)
@@ -519,47 +691,117 @@ struct bitset_test {
static void any(const Bitset& b)
{
BOOST_CHECK(b.any() == (b.count() > 0));
//BOOST_CHECK(b.any() == (b.count() > 0));
bool result = false;
for(std::size_t i = 0; i < b.size(); ++i)
if(b[i]) {
result = true;
break;
}
BOOST_CHECK(b.any() == result);
}
static void none(const Bitset& b)
{
bool result = true;
for(std::size_t i = 0; i < b.size(); ++i) {
if(b[i]) {
result = false;
break;
}
}
BOOST_CHECK(b.none() == result);
// sanity
BOOST_CHECK(b.none() == !b.any());
BOOST_CHECK(b.none() == (b.count() == 0));
}
static void subset(const Bitset& a, const Bitset& b)
{
if (a.is_subset_of(b)) {
for (std::size_t I = 0; I < a.size(); ++I)
if (a[I])
BOOST_CHECK(b[I]);
} else {
bool is_subset = true;
for (std::size_t I = 0; I < a.size(); ++I)
if (a[I] && !b[I]) {
BOOST_CHECK(a.size() == b.size()); // PRE
bool is_subset = true;
if (b.size()) { // could use b.any() but let's be safe
for(std::size_t i = 0; i < a.size(); ++i) {
if(a.test(i) && !b.test(i)) {
is_subset = false;
break;
}
BOOST_CHECK(is_subset == false);
}
}
else {
// sanity
BOOST_CHECK(a.count() == 0);
BOOST_CHECK(a.any() == false);
//is_subset = (a.any() == false);
}
BOOST_CHECK(a.is_subset_of(b) == is_subset);
}
static void proper_subset(const Bitset& a, const Bitset& b)
{
if (a.is_proper_subset_of(b)) {
for (std::size_t I = 0; I < a.size(); ++I)
if (a[I])
BOOST_CHECK(b[I]);
BOOST_CHECK(a.count() < b.count());
} else {
bool is_subset = true;
for (std::size_t I = 0; I < a.size(); ++I)
if (a[I] && !b[I]) {
is_subset = false;
break;
// PRE: a.size() == b.size()
BOOST_CHECK(a.size() == b.size());
bool is_proper = false;
if (b.size() != 0) {
// check it's a subset
subset(a, b);
// is it proper?
for (std::size_t i = 0; i < a.size(); ++i) {
if (!a.test(i) && b.test(i)) {
is_proper = true;
// sanity
BOOST_CHECK(a.count() < b.count());
BOOST_CHECK(b.any());
}
BOOST_CHECK(is_subset == false || a.count() >= b.count());
}
}
BOOST_CHECK(a.is_proper_subset_of(b) == is_proper);
if (is_proper)
BOOST_CHECK(b.is_proper_subset_of(a) != is_proper);// antisymmetry
}
static void intersects(const Bitset& a, const Bitset& b)
{
bool have_intersection = false;
typename Bitset::size_type m = a.size() < b.size() ? a.size() : b.size();
for(typename Bitset::size_type i = 0; i < m && !have_intersection; ++i)
if(a[i] == true && b[i] == true)
have_intersection = true;
BOOST_CHECK(a.intersects(b) == have_intersection);
// also check commutativity
BOOST_CHECK(b.intersects(a) == have_intersection);
}
static void find_first(const Bitset& b)
{
// find first non-null bit, if any
typename Bitset::size_type i = 0;
while (i < b.size() && b[i] == 0)
++i;
if (i == b.size())
BOOST_CHECK(b.find_first() == Bitset::npos); // not found;
else {
BOOST_CHECK(b.find_first() == i);
BOOST_CHECK(b.test(i) == true);
}
}
static void find_next(const Bitset& b, typename Bitset::size_type prev)
{
BOOST_CHECK(next_bit_on(b, prev) == b.find_next(prev));
}
static void operator_equal(const Bitset& a, const Bitset& b)
@@ -618,7 +860,28 @@ struct bitset_test {
else
return false;
}
static typename Bitset::size_type next_bit_on(const Bitset& b, typename Bitset::size_type prev)
{
// helper function for find_next()
//
if (b.none() == true || prev == Bitset::npos)
return Bitset::npos;
++prev;
if (prev >= b.size())
return Bitset::npos;
typename Bitset::size_type i = prev;
while (i < b.size() && b[i] == 0)
++i;
return i==b.size() ? Bitset::npos : i;
}
static void operator_less_than(const Bitset& a, const Bitset& b)
{
if (less_than(a, b))
@@ -706,22 +969,265 @@ struct bitset_test {
BOOST_CHECK((lhs - rhs) == (x -= rhs));
}
// operator<<(ostream,
// operator>>(istream,
//------------------------------------------------------------------------------
// I/O TESTS
// The following tests assume the results of extraction (i.e.: contents,
// state and width of is, contents of b) only depend on input (the string
// str). In other words, they don't consider "unexpected" errors such as
// stream corruption or out of memory. The reason is simple: if e.g. the
// stream buffer throws, the stream layer may eat the exception and
// transform it into a badbit. But we can't trust the stream state here,
// because one of the things that we want to test is exactly whether it
// is set correctly. Similarly for insertion.
//
// To provide for these cases would require that the test functions know
// in advance whether the stream buffer and/or allocations will fail, and
// when; that is, we should write both a special allocator and a special
// stream buffer capable of throwing "on demand" and pass them here.
static
void stream_read_write(const Bitset& out, const Bitset& in)
// Seems overkill for these kinds of unit tests.
//-------------------------------------------------------------------------
// operator<<( [basic_]ostream,
template <typename Stream>
static void stream_inserter(const Bitset & b,
Stream & s,
const char * file_name
)
{
Bitset x(in);
{
std::ofstream f("tmp");
f << out;
#if defined BOOST_OLD_IOSTREAMS
typedef char char_type;
typedef std::string string_type;
typedef ifstream corresponding_input_stream_type;
#else
typedef typename Stream::char_type char_type;
typedef std::basic_string<char_type> string_type;
typedef std::basic_ifstream<char_type> corresponding_input_stream_type;
std::ios::iostate except = s.exceptions();
#endif
typedef typename Bitset::size_type size_type;
std::streamsize w = s.width();
char_type fill_char = s.fill();
std::ios::iostate oldstate = s.rdstate();
bool stream_was_good = s.good();
bool did_throw = false;
try {
s << b;
}
{
std::ifstream f("tmp");
f >> x;
BOOST_CHECK(out == x);
#if defined BOOST_OLD_IOSTREAMS
catch(...) {
BOOST_CHECK(false);
}
#else
catch (const std::ios_base::failure &) {
BOOST_CHECK((except & s.rdstate()) != 0);
did_throw = true;
} catch (...) {
did_throw = true;
}
#endif
BOOST_CHECK(did_throw || !stream_was_good || (s.width() == 0));
if (!stream_was_good) {
BOOST_CHECK(s.good() == false);
// this should actually be oldstate == s.rdstate()
// but some implementations add badbit in the
// sentry constructor
//
BOOST_CHECK((oldstate & s.rdstate()) == oldstate);
BOOST_CHECK(s.width() == w);
}
else {
if(!did_throw)
BOOST_CHECK(s.width() == 0);
// This test require that os be an output _and_ input stream.
// Of course dynamic_bitset's operator << doesn't require that.
size_type total_len = w <= 0 || (size_type)(w) < b.size()? b.size() : w;
const string_type padding (total_len - b.size(), fill_char);
string_type expected;
boost::to_string(b, expected);
if ((s.flags() & std::ios::adjustfield) != std::ios::left)
expected = padding + expected;
else
expected = expected + padding;
assert(expected.length() == total_len);
// close, and reopen the file stream to verify contents
s.close();
corresponding_input_stream_type is(file_name);
string_type contents;
std::getline(is, contents, char_type());
BOOST_CHECK(contents == expected);
}
}
// operator>>( [basic_]istream
template <typename Stream, typename String>
static void stream_extractor(Bitset& b,
Stream& is,
String& str
)
{
// save necessary info then do extraction
//
const std::streamsize w = is.width();
Bitset a_copy(b);
bool stream_was_good = is.good();
bool did_throw = false;
#if defined BOOST_OLD_IOSTREAMS
bool has_stream_exceptions = false;
is >> b;
#else
const std::ios::iostate except = is.exceptions();
bool has_stream_exceptions = true;
try {
is >> b;
}
catch(const std::ios::failure &) {
did_throw = true;
}
// postconditions
BOOST_CHECK(except == is.exceptions()); // paranoid
#endif
//------------------------------------------------------------------
// postconditions
BOOST_CHECK(b.size() <= b.max_size());
if(w > 0)
BOOST_CHECK(b.size() <= static_cast<typename Bitset::size_type>(w));
// throw if and only if required
if(has_stream_exceptions) {
const bool exceptional_state = has_flags(is, is.exceptions());
BOOST_CHECK(exceptional_state == did_throw);
}
typedef typename String::size_type size_type;
typedef typename String::value_type Ch;
size_type after_digits = 0;
if(!stream_was_good) {
BOOST_CHECK(has_flags(is, std::ios::failbit));
BOOST_CHECK(b == a_copy);
BOOST_CHECK(is.width() == (did_throw ? w : 0));
}
else {
// stream was good(), parse the string;
// it may contain three parts, all of which are optional
// {spaces} {digits} {non-digits}
// opt opt opt
//
// The values of b.max_size() and is.width() may lead to
// ignore part of the digits, if any.
size_type pos = 0;
size_type len = str.length();
// {spaces}
for( ; pos < len && is_white_space(is, str[pos]); ++pos)
{}
size_type after_spaces = pos;
// {digits} or part of them
const typename Bitset::size_type max_digits =
w > 0 && static_cast<typename Bitset::size_type>(w) < b.max_size()
? w : b.max_size();
for( ; pos < len && (pos - after_spaces) < max_digits; ++pos) {
if(!is_one_or_zero(is, str[pos]))
break;
}
after_digits = pos;
size_type num_digits = after_digits - after_spaces;
// eofbit
if((after_digits == len && max_digits > num_digits ))
BOOST_CHECK(has_flags(is, std::ios::eofbit));
else
BOOST_CHECK(!has_flags(is, std::ios::eofbit));
// failbit <=> there are no digits, except for the library
// issue explained below.
//
if(num_digits == 0) {
if(after_digits == len && has_stream_exceptions &&
(is.exceptions() & std::ios::eofbit) != std::ios::goodbit) {
// This is a special case related to library issue 195:
// reaching eof when skipping whitespaces in the sentry ctor.
// The resolution says the sentry constructor should set *both*
// eofbit and failbit; but many implementations deliberately
// set eofbit only. See for instance:
// http://gcc.gnu.org/ml/libstdc++/2000-q1/msg00086.html
//
BOOST_CHECK(did_throw);
}
else {
BOOST_CHECK(has_flags(is, std::ios::failbit));
}
}
else
BOOST_CHECK(!has_flags(is, std::ios::failbit));
if(num_digits == 0 && after_digits == len) {
// The VC6 library has a bug/non-conformity in the sentry
// constructor. It uses code like
// // skip whitespaces...
// int_type _C = rdbuf()->sgetc();
// while (!_Tr::eq_int_type(_Tr::eof(), _C) ...
//
// For an empty file the while statement is never "entered"
// and the stream remains in good() state; thus the sentry
// object gives "true" when converted to bool. This is worse
// than the case above, because not only failbit is not set,
// but no bit is set at all, end we end up clearing the
// bitset though there's nothing in the file to be extracted.
// Note that the dynamic_bitset docs say a sentry object is
// constructed and then converted to bool, thus we rely on
// what the underlying library does.
//
#if !defined(BOOST_DINKUMWARE_STDLIB) || (BOOST_DINKUMWARE_STDLIB >= 306)
BOOST_CHECK(b == a_copy);
#else
BOOST_CHECK(b.empty() == true);
#endif
}
else {
String sub = str.substr(after_spaces, num_digits);
BOOST_CHECK(b == Bitset(sub));
}
// check width
BOOST_CHECK(is.width() == 0
|| (after_digits == len && num_digits == 0 && did_throw));
}
// clear the stream to allow further reading then
// retrieve any remaining chars with a single getline()
is.exceptions(std::ios::goodbit);
is.clear();
String remainder;
std::getline(is, remainder, Ch());
if(stream_was_good)
BOOST_CHECK(remainder == str.substr(after_digits));
else
BOOST_CHECK(remainder == str);
}
};
#endif // include guard

View File

@@ -1,90 +1,197 @@
// (C) Copyright Jeremy Siek 2001.
// 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.
#include <iostream>
#include <fstream>
#include <cmath> // for pow
#include <boost/limits.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/test/test_tools.hpp>
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 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)
//
// -----------------------------------------------------------
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/limits.hpp"
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
#define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0]))
template <typename Block>
void test_from_ulong(std::size_t n, unsigned long number)
// 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
template <typename Tests, typename String>
void run_string_tests(const String& s
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests)
)
{
boost::dynamic_bitset<Block> b(n, number);
bitset_test< boost::dynamic_bitset<Block> >::from_unsigned_long(b, number);
const std::size_t len = s.length();
const std::size_t step = len/4 ? len/4 : 1;
// bitset length determined by the string-related arguments
std::size_t i;
for (i = 0; i <= len/2 ; i += step) {
Tests::from_string(s, i, len/2); // len/2 - i bits
Tests::from_string(s, i, len); // len - i bits
Tests::from_string(s, i, 1 + len*2); // len - i bits
}
// bitset length explicitly specified
for (i = 0; i <= len/2; i += step) {
for (std::size_t sz = 0; sz <= len*4; sz+= step*2) {
Tests::from_string(s, i, len/2, sz);
Tests::from_string(s, i, len, sz);
Tests::from_string(s, i, 1 + len*2, sz);
}
}
}
// tests the do-the-right-thing constructor dispatch
template <typename Tests, typename T>
void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests)
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) )
{
const int bits_per_block = Tests::bits_per_block;
const int width = std::numeric_limits<T>::digits;
const T ma = (std::numeric_limits<T>::max)();
const T mi = (std::numeric_limits<T>::min)();
int sizes[] = {
0, 7*width/10, width, 13*width/10, 3*width,
7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
};
const T numbers[] = {
T(-1), T(-3), T(-8), T(-15), T(mi/2), T(mi),
T(0), T(1), T(3), T(8), T(15), T(ma/2), T(ma)
};
for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
for (std::size_t n = 0; n < BOOST_BITSET_TEST_COUNT(numbers); ++n ) {
// can match ctor from ulong or templated one
Tests::from_unsigned_long(sizes[s], numbers[n]);
typedef std::size_t compare_type;
const compare_type sz = sizes[s];
// this condition is to be sure that size is representable in T, so
// that for signed T's we avoid implementation-defined behavior [if ma
// is larger than what std::size_t can hold then this is ok for our
// purposes: our sizes are anyhow < max(size_t)], which in turn could
// make the first argument of from_unsigned_long() a small negative,
// later converted to a very large unsigned. Example: signed 8-bit
// char (CHAR_MAX=127), bits_per_block=64, sz = 192 > 127.
const bool fits =
sz <= static_cast<compare_type>(ma);
if (fits) {
// can match templated ctor only (so we test dispatching)
Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
}
}
}
}
template <typename Block>
void run_test_cases()
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
typedef bitset_test< boost::dynamic_bitset<Block> > Tests;
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test<bitset_type> Tests;
const int bits_per_block = bitset_type::bits_per_block;
std::string long_string(101, '0');
for (std::size_t j = 0; j < long_string.size(); ++j)
long_string[j] = '0' + (j % 2);
std::size_t N, ul_size = CHAR_BIT * sizeof(unsigned long),
block_size = CHAR_BIT * sizeof(Block);
unsigned long numbers[] = { 0, 40247,
std::numeric_limits<unsigned long>::max() };
const std::string long_string = get_long_string();
const Block all_1s = static_cast<Block>(-1);
//=====================================================================
// Test construction from unsigned long
for (std::size_t i = 0; i < 3; ++i) {
unsigned long number = numbers[i];
N = 0;
test_from_ulong<Block>(N, number);
{
typedef typename bitset_type::size_type size_type;
// NOTE:
//
// 1. keep this in sync with the numeric types supported
// for constructor dispatch (of course)
// 2. bool is tested separately; ugly and inelegant, but
// we don't have much time to think of a better solution
// which is likely to work on broken compilers
//
const int sizes[] = {
0, 1, 3,
7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
};
N = std::size_t(0.7 * double(ul_size));
test_from_ulong<Block>(N, number);
N = 1 * ul_size;
test_from_ulong<Block>(N, number);
N = std::size_t(1.3 * double(ul_size));
test_from_ulong<Block>(N, number);
N = std::size_t(0.7 * double(block_size));
test_from_ulong<Block>(N, number);
N = block_size;
test_from_ulong<Block>(N, number);
N = std::size_t(1.3 * double(block_size));
test_from_ulong<Block>(N, number);
N = 3 * block_size;
test_from_ulong<Block>(N, number);
const bool values[] = { false, true };
for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
for (std::size_t v = 0; v < BOOST_BITSET_TEST_COUNT(values); ++v) {
Tests::from_unsigned_long(sizes[s], values[v]);
Tests::from_unsigned_long(sizes[s] != 0, values[v]);
}
}
run_numeric_ctor_tests<Tests, char>();
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
run_numeric_ctor_tests<Tests, wchar_t>();
#endif
run_numeric_ctor_tests<Tests, signed char>();
run_numeric_ctor_tests<Tests, short int>();
run_numeric_ctor_tests<Tests, int>();
run_numeric_ctor_tests<Tests, long int>();
run_numeric_ctor_tests<Tests, unsigned char>();
run_numeric_ctor_tests<Tests, unsigned short>();
run_numeric_ctor_tests<Tests, unsigned int>();
run_numeric_ctor_tests<Tests, unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
run_numeric_ctor_tests<Tests, ::boost::long_long_type>();
run_numeric_ctor_tests<Tests, ::boost::ulong_long_type>();
#endif
}
//=====================================================================
// Test construction from a string
{
// case pos > str.size()
Tests::from_string(std::string(""), 1, 1);
{
// invalid arguments
Tests::from_string(std::string("x11"), 0, 3);
Tests::from_string(std::string("0y1"), 0, 3);
Tests::from_string(std::string("10z"), 0, 3);
run_string_tests<Tests>(std::string("")); // empty string
run_string_tests<Tests>(std::string("1"));
run_string_tests<Tests>(long_string);
# if !defined BOOST_NO_STD_WSTRING
// I need to decide what to do for non "C" locales here. On
// one hand I should have better tests. On the other one
// I don't want tests for dynamic_bitset to cope with locales,
// ctype::widen, etc. (but that's what you deserve when you
// don't separate concerns at the library level)
//
run_string_tests<Tests>(
std::wstring(L"11111000000111111111010101010101010101010111111"));
# endif
// Note that these are _valid_ arguments
Tests::from_string(std::string("x11y"), 1, 2);
Tests::from_string(std::string("x11"), 1, 10);
Tests::from_string(std::string("x11"), 1, 10, 10);
// valid arguments
Tests::from_string(std::string(""), 0, 0);
Tests::from_string(std::string("0"), 0, 1);
Tests::from_string(std::string("1"), 0, 1);
Tests::from_string(long_string, 0, long_string.size());
}
//=====================================================================
// Test construction from a block range
// test from_block_range
{
std::vector<Block> blocks;
Tests::from_block_range(blocks);
@@ -93,16 +200,31 @@ void run_test_cases()
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = ~Block(0);
blocks[2] = all_1s;
Tests::from_block_range(blocks);
}
{
std::vector<Block> blocks(101);
for (typename std::vector<Block>::size_type i = 0;
i < blocks.size(); ++i)
blocks[i] = i;
const unsigned int n = (std::numeric_limits<unsigned char>::max)();
std::vector<Block> blocks(n);
for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
blocks[i] = static_cast<Block>(i);
Tests::from_block_range(blocks);
}
//=====================================================================
// test to_block_range
{
bitset_type b;
Tests::to_block_range(b);
}
{
bitset_type b(1, 1ul);
Tests::to_block_range(b);
}
{
bitset_type b(long_string);
Tests::to_block_range(b);
}
//=====================================================================
// Test copy constructor
{
@@ -120,17 +242,50 @@ void run_test_cases()
//=====================================================================
// Test assignment operator
{
boost::dynamic_bitset<Block> a, b;
bitset_type a, b;
Tests::assignment_operator(a, b);
}
{
boost::dynamic_bitset<Block> a(std::string("1")), b(std::string("0"));
bitset_type a(std::string("1")), b(std::string("0"));
Tests::assignment_operator(a, b);
}
{
boost::dynamic_bitset<Block> a(long_string), b(long_string);
bitset_type a(long_string), b(long_string);
Tests::assignment_operator(a, b);
}
{
bitset_type a;
bitset_type b(long_string); // b greater than a, a empty
Tests::assignment_operator(a, b);
}
{
bitset_type a(std::string("0"));
bitset_type b(long_string); // b greater than a
Tests::assignment_operator(a, b);
}
//=====================================================================
// Test swap
{
bitset_type a;
bitset_type b(std::string("1"));
Tests::swap(a, b);
Tests::swap(b, a);
Tests::swap(a, a);
}
{
bitset_type a;
bitset_type b(long_string);
Tests::swap(a, b);
Tests::swap(b, a);
}
{
bitset_type a(std::string("0"));
bitset_type b(long_string);
Tests::swap(a, b);
Tests::swap(b, a);
Tests::swap(a, a);
Tests::swap(b, b);
}
//=====================================================================
// Test resize
{
@@ -173,6 +328,11 @@ void run_test_cases()
boost::dynamic_bitset<Block> a(std::string("1"));
Tests::append_bit(a);
}
{
const int size_to_fill_all_blocks = 4 * bits_per_block;
boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
Tests::append_bit(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::append_bit(a);
@@ -191,6 +351,11 @@ void run_test_cases()
boost::dynamic_bitset<Block> a(std::string("1"));
Tests::append_block(a);
}
{
const int size_to_fill_all_blocks = 4 * bits_per_block;
boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 15ul);
Tests::append_block(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::append_block(a);
@@ -207,15 +372,24 @@ void run_test_cases()
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = ~Block(0);
blocks[2] = all_1s;
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> a(std::string("1"));
std::vector<Block> blocks(101);
for (typename std::vector<Block>::size_type i = 0;
i < blocks.size(); ++i)
blocks[i] = i;
const unsigned int n = (std::numeric_limits<unsigned char>::max)();
std::vector<Block> blocks(n);
for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
blocks[i] = static_cast<Block>(i);
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> a;
a.append(Block(1));
a.append(Block(2));
Block x[] = {3, 4, 5};
std::size_t sz = sizeof(x) / sizeof(x[0]);
std::vector<Block> blocks(x, x + sz);
Tests::append_block_range(a, blocks);
}
{
@@ -223,7 +397,7 @@ void run_test_cases()
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = ~Block(0);
blocks[2] = all_1s;
Tests::append_block_range(a, blocks);
}
//=====================================================================
@@ -250,9 +424,14 @@ void run_test_cases()
int
test_main(int, char*[])
{
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
return EXIT_SUCCESS;
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return 0;
}

View File

@@ -1,27 +1,26 @@
// (C) Copyright Jeremy Siek 2001.
// 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.
#include <iostream>
#include <fstream>
#include <cmath> // for pow
#include <boost/dynamic_bitset.hpp>
#include <boost/test/test_tools.hpp>
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 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)
//
// -----------------------------------------------------------
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/config.hpp"
template <typename Block>
void run_test_cases()
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
typedef bitset_test< boost::dynamic_bitset<Block> > Tests;
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test< bitset_type > Tests;
const int bits_per_block = bitset_type::bits_per_block;
std::string long_string(101, '0');
for (std::size_t i = 0; i < long_string.size(); ++i)
long_string[i] = '0' + (i % 2);
std::string long_string = get_long_string();
//=====================================================================
// Test operator&=
@@ -99,8 +98,31 @@ void run_test_cases()
// Test operator<<=
{ // case pos == 0
std::size_t pos = 0;
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_left_assignment(b, pos);
{
boost::dynamic_bitset<Block> b;
Tests::shift_left_assignment(b, pos);
}
{
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_left_assignment(b, pos);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_left_assignment(b, pos);
}
}
{
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for (int i = 1; i <= how_many; ++i) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_left_assignment(b, multiple);
Tests::shift_left_assignment(b, non_multiple);
}
}
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
@@ -116,8 +138,32 @@ void run_test_cases()
// Test operator>>=
{ // case pos == 0
std::size_t pos = 0;
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_right_assignment(b, pos);
{
boost::dynamic_bitset<Block> b;
Tests::shift_right_assignment(b, pos);
}
{
boost::dynamic_bitset<Block> b(std::string("1010"));
Tests::shift_right_assignment(b, pos);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_right_assignment(b, pos);
}
}
{
// test with both multiple and
// non multiple of bits_per_block
const int how_many = 10;
for (int i = 1; i <= how_many; ++i) {
std::size_t multiple = i * bits_per_block;
std::size_t non_multiple = multiple - 1;
boost::dynamic_bitset<Block> b(long_string);
Tests::shift_right_assignment(b, multiple);
Tests::shift_right_assignment(b, non_multiple);
}
}
{ // case pos == size()/2
std::size_t pos = long_string.size() / 2;
@@ -172,7 +218,7 @@ void run_test_cases()
Tests::reset_all(b);
}
//=====================================================================
// Test b.reset(pos)
// Test b.reset(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::reset_one(b, 0);
@@ -214,7 +260,7 @@ void run_test_cases()
Tests::flip_all(b);
}
//=====================================================================
// Test b.flip(pos)
// Test b.flip(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::flip_one(b, 0);
@@ -230,11 +276,15 @@ void run_test_cases()
}
int
test_main(int argc, char*[])
{
test_main(int, char*[])
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
return EXIT_SUCCESS;
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return 0;
}

View File

@@ -1,30 +1,46 @@
// (C) Copyright Jeremy Siek 2001.
// 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.
#include <iostream>
#include <fstream>
#include <cmath> // for pow
#include <boost/dynamic_bitset.hpp>
#include <boost/test/test_tools.hpp>
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 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)
//
// -----------------------------------------------------------
#include <assert.h>
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/limits.hpp"
#include "boost/config.hpp"
template <typename Block>
void run_test_cases()
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
typedef bitset_test< boost::dynamic_bitset<Block> > Tests;
// a bunch of typedefs which will be handy later on
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test<bitset_type> Tests;
// typedef typename bitset_type::size_type size_type; // unusable with Borland 5.5.1
std::string long_string(101, '0');
for (std::size_t i = 0; i < long_string.size(); ++i)
long_string[i] = '0' + (i % 2);
std::size_t ul_size = CHAR_BIT * sizeof(unsigned long);
std::string long_string = get_long_string();
std::size_t ul_width = std::numeric_limits<unsigned long>::digits;
//=====================================================================
// Test b.empty()
{
bitset_type b;
Tests::empty(b);
}
{
bitset_type b(1, 1ul);
Tests::empty(b);
}
{
bitset_type b(bitset_type::bits_per_block
+ bitset_type::bits_per_block/2, 15ul);
Tests::empty(b);
}
//=====================================================================
// Test b.to_long()
{
@@ -32,7 +48,21 @@ void run_test_cases()
Tests::to_ulong(b);
}
{
std::string ul_str(ul_size, '1');
boost::dynamic_bitset<Block> b(std::string("1"));
Tests::to_ulong(b);
}
{
boost::dynamic_bitset<Block> b(bitset_type::bits_per_block,
static_cast<unsigned long>(-1));
Tests::to_ulong(b);
}
{
std::string str(ul_width - 1, '1');
boost::dynamic_bitset<Block> b(str);
Tests::to_ulong(b);
}
{
std::string ul_str(ul_width, '1');
boost::dynamic_bitset<Block> b(ul_str);
Tests::to_ulong(b);
}
@@ -64,6 +94,14 @@ void run_test_cases()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::count(b);
}
{
boost::dynamic_bitset<Block> b(std::string("1"));
Tests::count(b);
}
{
boost::dynamic_bitset<Block> b(8, 255ul);
Tests::count(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::count(b);
@@ -167,6 +205,132 @@ void run_test_cases()
Tests::proper_subset(a, b);
}
//=====================================================================
// Test intersects
{
bitset_type a; // empty
bitset_type b;
Tests::intersects(a, b);
}
{
bitset_type a;
bitset_type b(5, 8ul);
Tests::intersects(a, b);
}
{
bitset_type a(8, 0ul);
bitset_type b(15, 0ul);
b[9] = 1;
Tests::intersects(a, b);
}
{
bitset_type a(15, 0ul);
bitset_type b(22, 0ul);
a[14] = b[14] = 1;
Tests::intersects(a, b);
}
//=====================================================================
// Test find_first
{
// empty bitset
bitset_type b;
Tests::find_first(b);
}
{
// bitset of size 1
bitset_type b(1, 1ul);
Tests::find_first(b);
}
{
// all-0s bitset
bitset_type b(4 * bitset_type::bits_per_block, 0ul);
Tests::find_first(b);
}
{
// first bit on
bitset_type b(1, 1ul);
Tests::find_first(b);
}
{
// last bit on
bitset_type b(4 * bitset_type::bits_per_block - 1, 0ul);
b.set(b.size() - 1);
Tests::find_first(b);
}
//=====================================================================
// Test find_next
{
// empty bitset
bitset_type b;
// check
Tests::find_next(b, 0);
Tests::find_next(b, 1);
Tests::find_next(b, 200);
Tests::find_next(b, b.npos);
}
{
// bitset of size 1 (find_next can never find)
bitset_type b(1, 1ul);
// check
Tests::find_next(b, 0);
Tests::find_next(b, 1);
Tests::find_next(b, 200);
Tests::find_next(b, b.npos);
}
{
// all-1s bitset
bitset_type b(16 * bitset_type::bits_per_block);
b.set();
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for(typename bitset_type::size_type i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
}
Tests::find_next(b, b.npos);
}
{
// a bitset with 1s at block boundary only
const int num_blocks = 32;
const int block_width = bitset_type::bits_per_block;
bitset_type b(num_blocks * block_width);
typename bitset_type::size_type i = block_width - 1;
for ( ; i < b.size(); i += block_width) {
b.set(i);
typename bitset_type::size_type first_in_block = i - (block_width - 1);
b.set(first_in_block);
}
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for (i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
}
Tests::find_next(b, b.npos);
}
{
// bitset with alternate 1s and 0s
const typename bitset_type::size_type sz = 1000;
bitset_type b(sz);
typename bitset_type::size_type i = 0;
for ( ; i < sz; ++i) {
b[i] = (i%2 == 0);
}
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for (i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
}
Tests::find_next(b, b.npos);
}
//=====================================================================
// Test operator==
{
boost::dynamic_bitset<Block> a, b;
@@ -236,6 +400,10 @@ void run_test_cases()
boost::dynamic_bitset<Block> a(std::string("1")), b(std::string("1"));
Tests::operator_less_than(a, b);
}
{
boost::dynamic_bitset<Block> a(std::string("10")), b(std::string("11"));
Tests::operator_less_than(a, b);
}
{
boost::dynamic_bitset<Block> a(long_string), b(long_string);
Tests::operator_less_than(a, b);
@@ -387,7 +555,7 @@ void run_test_cases()
assert(a >= b);
}
//=====================================================================
// Test b.test(pos)
// Test b.test(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::test_bit(b, 0);
@@ -401,7 +569,7 @@ void run_test_cases()
Tests::test_bit(b, long_string.size()/2);
}
//=====================================================================
// Test b << pos
// Test b << pos
{ // case pos == 0
std::size_t pos = 0;
boost::dynamic_bitset<Block> b(std::string("1010"));
@@ -418,7 +586,7 @@ void run_test_cases()
Tests::operator_shift_left(b, pos);
}
//=====================================================================
// Test b >> pos
// Test b >> pos
{ // case pos == 0
std::size_t pos = 0;
boost::dynamic_bitset<Block> b(std::string("1010"));
@@ -506,30 +674,18 @@ void run_test_cases()
boost::dynamic_bitset<Block> lhs(long_string.size(), 1), rhs(long_string);
Tests::operator_sub(lhs, rhs);
}
//=====================================================================
// Test stream operator<< and operator>>
{
boost::dynamic_bitset<Block> b;
boost::dynamic_bitset<Block> x(b.size());
Tests::stream_read_write(b, x);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
boost::dynamic_bitset<Block> x(b.size());
Tests::stream_read_write(b, x);
}
{
boost::dynamic_bitset<Block> b(long_string);
boost::dynamic_bitset<Block> x(b.size());
Tests::stream_read_write(b, x);
}
}
int
test_main(int, char*[])
{
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
return EXIT_SUCCESS;
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return 0;
}

335
dyn_bitset_unit_tests4.cpp Normal file
View File

@@ -0,0 +1,335 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 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)
//
// -----------------------------------------------------------
#include <fstream>
#include <string>
#include <cstddef> // for std::size_t
#include <stdexcept> // for std::logic_error
#include <assert.h>
#include "boost/config.hpp"
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#endif
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/detail/workaround.hpp"
// Codewarrior 8.3 for Win fails without this.
// Thanks Howard Hinnant ;)
#if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
# pragma parse_func_templ off
#endif
#if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
# 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() )
{
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);
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) )
{
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)
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
static std::string strings[] = {
std::string(""),
std::string("0"),
std::string("1"),
std::string("11100"),
get_long_string()
};
char fill_chars[] = { '*', 'x', ' ' };
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]);
std::fstream not_good_stream("dynamic_bitset_tests - this file shouldn't exist",
std::ios::in);
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());
assert( (std::numeric_limits<std::streamsize>::max)()
>=(std::streamsize)(1+slen*2) );
for (std::size_t ci = 0; ci < num_chars; ++ci) {
// note how "negative widths" are tested too
const std::streamsize widths[] = { -1 - slen/2, 0, slen/2, 1 + slen*2 };
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
for (std::size_t wi = 0; wi < num_widths; ++wi) {
std::streamsize w = widths[wi];
{
// test 0 - stream !good()
if(not_good_stream.good())
throw std::logic_error("Error in operator << tests"
" - please, double check");
bitset_type b(strings[si]);
not_good_stream.width(w);
not_good_stream.fill(fill_chars[ci]);
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
Tests::stream_inserter(b, not_good_stream, "<unused_string>");
}
{
// test 1a - file stream
bitset_type b(strings[si]);
std::ofstream file(test_file_name(), std::ios::trunc);
file.width(w);
file.fill(fill_chars[ci]);
file.exceptions(masks[mi]);
Tests::stream_inserter(b, file, test_file_name());
}
{
//NOTE: there are NO string stream tests
}
#if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
{
// test 1b - wide file stream
bitset_type b(strings[si]);
std::wofstream file(test_file_name());
file.width(w);
file.fill(fill_chars[ci]);
file.exceptions(masks[mi]);
Tests::stream_inserter(b, file, test_file_name());
}
#endif
}
}
}
} // 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>>.
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
const std::string spaces = "\t\n "; //"\t\n\v\f ";
const std::string long_string = get_long_string();
/*const*/ static std::string strings[] = {
// NOTE: "const" gives the usual problems with Borland
// (in Tests::stream_extractor instantiation)
#if !(defined __BORLANDC__ \
&& BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)))
// Borland 5.5.1 with RW library crashes
// empty string
std::string(""),
// no bitset
spaces,
#endif
// no bitset
std::string("x"),
std::string("\t xyz"),
// bitset of size 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 "),
// 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
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));
std::streamsize widths[] = { -1, 0, slen/2, slen, 1 + slen*2 };
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
for(std::size_t wi = 0; wi < num_widths; ++wi) {
const std::streamsize w = widths[wi];
// test 0 - !good() stream
{
if(not_good_stream.good())
throw std::logic_error("Error in operator >> tests"
" - please, double check");
bitset_type b(1, 15ul); // note: b is not empty
not_good_stream.width(w);
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
std::string irrelevant;
Tests::stream_extractor(b, not_good_stream, irrelevant);
}
// test 1a - (narrow) file stream
{
bitset_type b(1, 255ul);
{
std::ofstream f(test_file_name());
f << strings[si];
}
std::ifstream f(test_file_name());
f.width(w);
f.exceptions(masks[mi]);
Tests::stream_extractor(b, f, strings[si]);
}
#if !defined(BOOST_NO_STRINGSTREAM)
// test 2a - stringstream
{
bitset_type b(1, 255ul);
std::istringstream stream(strings[si]);
stream.width(w);
stream.exceptions(masks[mi]);
Tests::stream_extractor(b, stream, strings[si]);
}
#endif
#if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
// test 1b - wchar_t file stream
{
std::wstring wstr = widen_string(strings[si]);
bitset_type b(1, 255ul);
{
std::basic_ofstream<wchar_t> of(test_file_name());
of << wstr;
}
std::basic_ifstream<wchar_t> f(test_file_name());
f.width(w);
f.exceptions(masks[mi]);
Tests::stream_extractor(b, f, wstr);
}
// test 2b - wstringstream
{
bitset_type b(1, 255ul);
std::wstring wstr = widen_string(strings[si]);
std::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; ...)
}
//=====================================================================
// << Any other tests go here >>
// .....
}
int
test_main(int, char*[])
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return 0;
}

File diff suppressed because it is too large Load Diff

24
example/Jamfile Normal file
View File

@@ -0,0 +1,24 @@
// -----------------------------------------------------------
// Copyright (c) 2002 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)
//
// -----------------------------------------------------------
exe timing_tests
: timing_tests.cpp
;
exe example1
: example1.cpp
;
exe example2
: example2.cpp
;
exe example3
: example3.cpp
;

35
example/example1.cpp Normal file
View File

@@ -0,0 +1,35 @@
// (C) Copyright Jeremy Siek 2001.
// 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 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
// bitset from most-significant to least-significant, since that is
// the format most people are used to reading.
//
// The output is:
//
// 11001
// 10011
// ---------------------------------------------------------------------
#include <iostream>
#include <boost/dynamic_bitset.hpp>
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];
std::cout << "\n";
std::cout << x << "\n";
return 0;
}

32
example/example2.cpp Normal file
View File

@@ -0,0 +1,32 @@
// (C) Copyright Jeremy Siek 2001.
// 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)
//
// Sample output:
//
// bits(0) = 00
// bits(1) = 01
// bits(2) = 10
// bits(3) = 11
#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main()
{
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<> b2(2, 2ul);
std::cout << "bits(2) = " << b2 << std::endl;
const boost::dynamic_bitset<> b3(2, 3ul);
std::cout << "bits(3) = " << b3 << std::endl;
return 0;
}

71
example/example3.cpp Normal file
View File

@@ -0,0 +1,71 @@
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2008 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)
//
// Sample run:
//
// mask = 101010101010
// x.size() = 0
// Enter a bitset in binary: x = 100100010
//
// Input number: 100100010
// x.size() is now: 9
// As unsigned long: 290
// Mask (possibly resized): 010101010
// And with mask: 000100010
// Or with mask: 110101010
// Shifted left by 1: 001000100
// Shifted right by 1: 010010001
#include "boost/dynamic_bitset.hpp"
#include <ostream>
#include <iostream>
int main()
{
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) {
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;
try {
ul = x.to_ulong();
} catch(std::overflow_error &) {
fits_in_ulong = false;
}
std::cout << "As unsigned long: ";
if(fits_in_ulong) {
std::cout << ul;
} else {
std::cout << "(overflow exception)";
}
std::cout << std::endl;
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;
}
return 0;
}

139
example/timing_tests.cpp Normal file
View File

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

View File

@@ -1,26 +0,0 @@
// (C) Copyright Jeremy Siek 2001. 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.
// Sample output:
// 1
// 1
// 0
// 0
// 1
#include <iostream>
#include <boost/dynamic_bitset.hpp>
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];
std::cout << "\n";
std::cout << x << "\n";
return EXIT_SUCCESS;
}

View File

@@ -1,30 +0,0 @@
// (C) Copyright Jeremy Siek 2001. 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.
//
// Sample output:
// bits(0) = 00
// bits(1) = 01
// bits(2) = 10
// bits(3) = 11
#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main()
{
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<> b2(2, 2ul);
std::cout << "bits(2) = " << b2 << std::endl;
const boost::dynamic_bitset<> b3(2, 3ul);
std::cout << "bits(3) = " << b3 << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -1,36 +0,0 @@
// (C) Copyright Jeremy Siek 2001. 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.
//
// Sample output:
// mask = 101010101010
// Enter a 12-bit bitset in binary: 100110101101
// x = 100110101101
// As ulong: 2477
// And with mask: 100010101000
// Or with mask: 101110101111
#include <iostream>
#include <boost/dynamic_bitset.hpp>
int main(int, char*[]) {
const boost::dynamic_bitset<> mask(12, 2730ul);
std::cout << "mask = " << mask << std::endl;
boost::dynamic_bitset<> x(12);
std::cout << "x.size()=" << x.size() << std::endl;
std::cout << "Enter a 12-bit bitset in binary: " << std::flush;
if (std::cin >> x) {
std::cout << "input number: " << x << std::endl;
std::cout << "As unsigned long: " << x.to_ulong() << std::endl;
std::cout << "And with mask: " << (x & mask) << std::endl;
std::cout << "Or with mask: " << (x | mask) << std::endl;
std::cout << "Shifted left: " << (x << 1) << std::endl;
std::cout << "Shifted right: " << (x >> 1) << std::endl;
}
return EXIT_SUCCESS;
}

View File

@@ -1,129 +1,86 @@
// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002.
// -----------------------------------------------------------
//
// 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.
// With optimizations by Gennaro Prota.
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 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)
//
// -----------------------------------------------------------
#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
#include <cstddef>
#include "boost/config.hpp"
#include "boost/detail/iterator.hpp"
#include "boost/detail/workaround.hpp"
#if !(defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || defined(__BORLANDC__))
#define BOOST_DYN_BITSET_USE_FRIENDS
#endif
namespace boost {
namespace detail {
namespace dynamic_bitset_impl {
// Forward references
template <typename BlockInputIterator>
std::size_t initial_num_blocks(BlockInputIterator first,
BlockInputIterator last,
std::input_iterator_tag);
template <typename BlockForwardIterator>
std::size_t initial_num_blocks(BlockForwardIterator first,
BlockForwardIterator last,
std::forward_iterator_tag);
// The following 2 classes make sure that the bitset
// gets allocated in an exception safe manner
template <typename Allocator>
class dynamic_bitset_alloc_base {
public:
dynamic_bitset_alloc_base(const Allocator& alloc)
: m_alloc(alloc) { }
protected:
Allocator m_alloc;
};
template <typename Block, typename Allocator>
class dynamic_bitset_base :
#ifdef BOOST_DYN_BITSET_USE_FRIENDS
protected
#else
public
#endif
dynamic_bitset_alloc_base<Allocator>
// 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)
{
typedef std::size_t size_type;
#ifndef BOOST_DYN_BITSET_USE_FRIENDS
public:
#endif
enum { bits_per_block = CHAR_BIT * sizeof(Block) };
public:
dynamic_bitset_base()
: m_bits(0), m_num_bits(0), m_num_blocks(0) { }
return static_cast<const unsigned char *>(static_cast<const void *>(p));
}
dynamic_bitset_base(size_type num_bits, const Allocator& alloc)
: dynamic_bitset_alloc_base<Allocator>(alloc),
m_bits(dynamic_bitset_alloc_base<Allocator>::
m_alloc.allocate(calc_num_blocks(num_bits), static_cast<void const *>(0))),
m_num_bits(num_bits),
m_num_blocks(calc_num_blocks(num_bits))
{
using namespace std;
memset(m_bits, 0, m_num_blocks * sizeof(Block)); // G.P.S. ask to Jeremy
}
~dynamic_bitset_base() {
if (m_bits)
this->m_alloc.deallocate(m_bits, m_num_blocks);
}
#ifdef BOOST_DYN_BITSET_USE_FRIENDS
protected:
#endif
Block* m_bits;
size_type m_num_bits;
size_type m_num_blocks;
static size_type word(size_type bit) { return bit / bits_per_block; } // [gps]
static size_type offset(size_type bit){ return bit % bits_per_block; } // [gps]
static Block mask1(size_type bit) { return Block(1) << offset(bit); }
static Block mask0(size_type bit) { return ~(Block(1) << offset(bit)); }
static size_type calc_num_blocks(size_type num_bits)
{ return (num_bits + bits_per_block - 1) / bits_per_block; }
template<typename T, int amount, int width /* = default */>
struct shifter
{
static void left_shift(T & v) {
amount >= width ? (v = 0)
: (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount));
}
};
// ------- count function implementation --------------
// ------- count table implementation --------------
typedef unsigned char byte_t;
// only count<true> has a definition
#if 0
// This was giving Intel C++ and Borland C++ trouble -JGS
template <bool = true> struct count;
template <> struct count <true> {
#else
template <bool bogus = true>
struct count {
#endif
typedef byte_t element_type;
static const byte_t table[];
BOOST_STATIC_CONSTANT (unsigned int, max_bit = 8); // must be a power of two
typedef unsigned char byte_type;
// These two entities
//
// enum mode { access_by_bytes, access_by_blocks };
// template <mode> struct mode_to_type {};
//
// were removed, since the regression logs (as of 24 Aug 2008)
// showed that several compilers had troubles with recognizing
//
// const mode m = access_by_bytes
//
// as a constant expression
//
// * So, we'll use bool, instead of enum *.
//
template <bool value>
struct value_to_type
{
value_to_type() {}
};
//typedef count<true> table_t;
const bool access_by_bytes = true;
const bool access_by_blocks = false;
// the table: wrapped in a class template, so
// that it is only instantiated if/when needed
//
#if 0
// Intel C++ and Borland C++ trouble -JGS
template <>
const byte_t count <true>::table[] =
#else
template <bool bogus>
const byte_t count<bogus>::table[] =
#endif
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
//
@@ -138,39 +95,135 @@ namespace boost {
};
// overload for access by bytes
//
template <typename Iterator>
inline std::size_t do_count(Iterator first, std::size_t length,
int /*dummy param*/,
value_to_type<access_by_bytes>* )
{
std::size_t num = 0;
if (length)
{
const byte_type * p = object_representation(&*first);
length *= sizeof(*first);
do {
num += count_table<>::table[*p];
++p;
--length;
} while (length);
}
return num;
}
// overload for access by blocks
//
template <typename Iterator, typename ValueType>
inline std::size_t do_count(Iterator first, std::size_t length, ValueType,
value_to_type<access_by_blocks>*)
{
std::size_t num = 0;
while (length){
ValueType value = *first;
while (value) {
num += count_table<>::table[value & ((1u<<table_width) - 1)];
value >>= table_width;
}
++first;
--length;
}
return num;
}
// -------------------------------------------------------
template <typename BlockInputIterator>
std::size_t initial_num_blocks(BlockInputIterator first,
BlockInputIterator last,
std::input_iterator_tag)
{
return 0;
// 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) {
typedef typename T::allocator_type allocator_type;
const typename allocator_type::size_type alloc_max =
v.get_allocator().max_size();
const typename T::size_type container_max = v.max_size();
return alloc_max < container_max?
alloc_max :
container_max;
}
template <typename BlockForwardIterator>
std::size_t initial_num_blocks(BlockForwardIterator first,
BlockForwardIterator last,
std::forward_iterator_tag)
{
std::size_t n = 0;
while (first != last)
++first, ++n;
return n;
}
// for static_asserts
template <typename T>
struct allowed_block_type {
enum { value = T(-1) > 0 }; // ensure T has no sign
};
template <typename BlockInputIterator>
std::size_t initial_num_blocks(BlockInputIterator first,
BlockInputIterator last)
{
typename detail::iterator_traits<BlockInputIterator>::iterator_category cat;
return initial_num_blocks(first, last, cat);
}
template <>
struct allowed_block_type<bool> {
enum { value = false };
};
template <typename T>
struct is_numeric {
enum { value = false };
};
# define BOOST_dynamic_bitset_is_numeric(x) \
template<> \
struct is_numeric< x > { \
enum { value = true }; \
} /**/
BOOST_dynamic_bitset_is_numeric(bool);
BOOST_dynamic_bitset_is_numeric(char);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_dynamic_bitset_is_numeric(wchar_t);
#endif
BOOST_dynamic_bitset_is_numeric(signed char);
BOOST_dynamic_bitset_is_numeric(short int);
BOOST_dynamic_bitset_is_numeric(int);
BOOST_dynamic_bitset_is_numeric(long int);
BOOST_dynamic_bitset_is_numeric(unsigned char);
BOOST_dynamic_bitset_is_numeric(unsigned short);
BOOST_dynamic_bitset_is_numeric(unsigned int);
BOOST_dynamic_bitset_is_numeric(unsigned long);
#if defined(BOOST_HAS_LONG_LONG)
BOOST_dynamic_bitset_is_numeric(::boost::long_long_type);
BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type);
#endif
// intentionally omitted
//BOOST_dynamic_bitset_is_numeric(float);
//BOOST_dynamic_bitset_is_numeric(double);
//BOOST_dynamic_bitset_is_numeric(long double);
#undef BOOST_dynamic_bitset_is_numeric
} // dynamic_bitset_impl
} // namespace detail
} // namespace boost
#endif // BOOST_DETAIL_DYNAMIC_BITSET_HPP
#endif // include guard

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
// -----------------------------------------------------------
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 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)
//
// -----------------------------------------------------------
#ifndef BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#define BOOST_DYNAMIC_BITSET_CONFIG_HPP_GP_20040424
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
// support for pre 3.0 libstdc++ - thanks Phil Edwards!
#if defined (__STL_CONFIG_H) && !defined (__STL_USE_NEW_IOSTREAMS)
# define BOOST_OLD_IOSTREAMS
#endif
// no-op function to workaround gcc bug c++/8419
//
namespace boost { namespace detail {
template <typename T> T make_non_const(T t) { return t; }
}}
#if defined(__GNUC__)
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) \
(boost::detail::make_non_const(expr))
#else
# define BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(expr) (expr)
#endif
//
#if (defined __BORLANDC__ && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))) \
|| (defined BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
#endif
// if we can't use friends then we simply expose private members
//
#if defined(BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS)
#define BOOST_DYNAMIC_BITSET_PRIVATE public
#else
#define BOOST_DYNAMIC_BITSET_PRIVATE private
#endif
// A couple of macros to cope with libraries without locale
// support. The first macro must be used to declare a reference
// to a ctype facet. The second one to widen a char by using
// that ctype object. If facets and locales aren't available
// the first macro is a no-op and the second one just expands
// to its parameter c.
//
#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_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
#endif
#endif // include guard

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,13 @@
// (C) Copyright Chuck Allison and Jeremy Siek 2001, 2002.
// -----------------------------------------------------------
//
// 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.
// See http://www.boost.org/libs/dynamic_bitset for documentation.
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2004 Gennaro Prota
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// -----------------------------------------------------------
#ifndef BOOST_DYNAMIC_BITSET_FWD_HPP
#define BOOST_DYNAMIC_BITSET_FWD_HPP
@@ -19,6 +20,6 @@ template <typename Block = unsigned long,
typename Allocator = std::allocator<Block> >
class dynamic_bitset;
} // namespace boost
}
#endif // BOOST_DYNAMIC_BITSET_FWD_HPP
#endif // include guard

View File

@@ -0,0 +1,39 @@
// -----------------------------------------------------------
// lowest_bit.hpp
//
// Position of the lowest bit 'on'
//
// Copyright (c) 2003-2004, 2008 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)
//
// -----------------------------------------------------------
#ifndef BOOST_LOWEST_BIT_HPP_GP_20030301
#define BOOST_LOWEST_BIT_HPP_GP_20030301
#include <assert.h>
#include "boost/pending/integer_log2.hpp"
namespace boost {
template <typename T>
int lowest_bit(T x) {
assert(x >= 1); // PRE
// clear all bits on except the rightmost one,
// then calculate the logarithm base 2
//
return boost::integer_log2<T>( x - ( x & (x-1) ) );
}
}
#endif // include guard

View File

@@ -1,9 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=dynamic_bitset.html">
<meta http-equiv=refresh content="0; URL=dynamic_bitset.html">
<title>Automatic redirection</title>
</head>
<body>
Automatic redirection failed, please go to
<a href="dynamic_bitset.html">dynamic_bitset.html</a>.
<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
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@@ -1,101 +0,0 @@
// boost::dynamic_bitset timing test ---------------------------------------//
// (C) Copyright Gennaro Prota 2002.
// 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.
//****************************************************************************//
// WARNING:
// ~~~~~~~
// This is a preliminary version, for internal testing only.
// For now, it stresses the count() function only and has been executed
// on a very few platforms. The previous version, for instance, was never
// executed on MSVC (boost::bitset<> didn't even compile with it) and at
// the first try it crashed at startup, presumably because of a linker bug.
// To cope with it, the definition of
//
// template <typename T> void timing_test()
//
// has been moved before the definition of main()
//
// LAST MODIFIED: 2 Aug 2002
//****************************************************************************//
#include <iostream>
#include <typeinfo>
#include <iomanip>
#include "boost/timer.hpp"
#include "boost/dynamic_bitset.hpp"
#include "boost/cstdlib.hpp"
void prologue()
{
std::cout << "Compiler: " << BOOST_COMPILER << '\n';
std::cout << "STLPort used? ";
# ifdef _STLPORT_VERSION
std::cout << "Yes, v." << std::hex << _STLPORT_VERSION;
# else
std::cout << "No.";
# endif
std::cout << std::dec << "\n";
}
template <typename T>
void timing_test()
{
const unsigned long num = 10000;
std::size_t dummy = 0; // this is printed at the end of the test,
// to prevent the optimizer to eliminate
// the call to count() in the loop below :-)
std::cout << "\n\nTimings for dynamic_bitset<" << typeid(T).name()
<< "> [" << num << " iterations]\n";
std::cout << "--------------------------------------------------\n";
{ // new implementation
boost::timer time;
for (unsigned long i=0; i<num; ++i) {
boost::dynamic_bitset<T> bs(std::size_t(5000), i);
dummy += bs.count();
}
const double elaps = time.elapsed();
std::cout << "Elapsed: " << elaps << '\n';
}
std::cout << "(total count: " << dummy << ")\n";
}
int main()
{
prologue();
timing_test<unsigned short>();
timing_test<unsigned int>();
timing_test<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
timing_test<unsigned long long>();
# endif
return boost::exit_success;
}