dynamic_bitset.hpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761
  1. // -----------------------------------------------------------
  2. //
  3. // Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
  4. // Copyright (c) 2003-2006, 2008 Gennaro Prota
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // -----------------------------------------------------------
  11. #ifndef BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP
  12. #define BOOST_DYNAMIC_BITSET_DYNAMIC_BITSET_HPP
  13. #include <assert.h>
  14. #include <string>
  15. #include <stdexcept>
  16. #include <algorithm>
  17. #include <vector>
  18. #include <climits> // for CHAR_BIT
  19. #include "boost/dynamic_bitset/config.hpp"
  20. #ifndef BOOST_NO_STD_LOCALE
  21. # include <locale>
  22. #endif
  23. #if defined(BOOST_OLD_IOSTREAMS)
  24. # include <iostream.h>
  25. # include <ctype.h> // for isspace
  26. #else
  27. # include <istream>
  28. # include <ostream>
  29. #endif
  30. #include "boost/dynamic_bitset_fwd.hpp"
  31. #include "boost/detail/dynamic_bitset.hpp"
  32. #include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter)
  33. #include "boost/static_assert.hpp"
  34. #include "boost/limits.hpp"
  35. #include "boost/pending/lowest_bit.hpp"
  36. namespace boost {
  37. template <typename Block, typename Allocator>
  38. class dynamic_bitset
  39. {
  40. // Portability note: member function templates are defined inside
  41. // this class definition to avoid problems with VC++. Similarly,
  42. // with the member functions of nested classes.
  43. //
  44. // [October 2008: the note above is mostly historical; new versions
  45. // of VC++ are likely able to digest a more drinking form of the
  46. // code; but changing it now is probably not worth the risks...]
  47. BOOST_STATIC_ASSERT((bool)detail::dynamic_bitset_impl::allowed_block_type<Block>::value);
  48. public:
  49. typedef Block block_type;
  50. typedef Allocator allocator_type;
  51. typedef std::size_t size_type;
  52. typedef block_type block_width_type;
  53. BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits<Block>::digits));
  54. BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
  55. public:
  56. // A proxy class to simulate lvalues of bit type.
  57. //
  58. class reference
  59. {
  60. friend class dynamic_bitset<Block, Allocator>;
  61. // the one and only non-copy ctor
  62. reference(block_type & b, block_type pos)
  63. :m_block(b),
  64. m_mask( (assert(pos < bits_per_block),
  65. block_type(1) << pos )
  66. )
  67. { }
  68. void operator&(); // left undefined
  69. public:
  70. // copy constructor: compiler generated
  71. operator bool() const { return (m_block & m_mask) != 0; }
  72. bool operator~() const { return (m_block & m_mask) == 0; }
  73. reference& flip() { do_flip(); return *this; }
  74. reference& operator=(bool x) { do_assign(x); return *this; } // for b[i] = x
  75. reference& operator=(const reference& rhs) { do_assign(rhs); return *this; } // for b[i] = b[j]
  76. reference& operator|=(bool x) { if (x) do_set(); return *this; }
  77. reference& operator&=(bool x) { if (!x) do_reset(); return *this; }
  78. reference& operator^=(bool x) { if (x) do_flip(); return *this; }
  79. reference& operator-=(bool x) { if (x) do_reset(); return *this; }
  80. private:
  81. block_type & m_block;
  82. const block_type m_mask;
  83. void do_set() { m_block |= m_mask; }
  84. void do_reset() { m_block &= ~m_mask; }
  85. void do_flip() { m_block ^= m_mask; }
  86. void do_assign(bool x) { x? do_set() : do_reset(); }
  87. };
  88. typedef bool const_reference;
  89. // constructors, etc.
  90. explicit
  91. dynamic_bitset(const Allocator& alloc = Allocator());
  92. explicit
  93. dynamic_bitset(size_type num_bits, unsigned long value = 0,
  94. const Allocator& alloc = Allocator());
  95. // WARNING: you should avoid using this constructor.
  96. //
  97. // A conversion from string is, in most cases, formatting,
  98. // and should be performed by using operator>>.
  99. //
  100. // NOTE:
  101. // Leave the parentheses around std::basic_string<CharT, Traits, Alloc>::npos.
  102. // g++ 3.2 requires them and probably the standard will - see core issue 325
  103. // NOTE 2:
  104. // split into two constructors because of bugs in MSVC 6.0sp5 with STLport
  105. template <typename CharT, typename Traits, typename Alloc>
  106. dynamic_bitset(const std::basic_string<CharT, Traits, Alloc>& s,
  107. typename std::basic_string<CharT, Traits, Alloc>::size_type pos,
  108. typename std::basic_string<CharT, Traits, Alloc>::size_type n,
  109. size_type num_bits = npos,
  110. const Allocator& alloc = Allocator())
  111. :m_bits(alloc),
  112. m_num_bits(0)
  113. {
  114. init_from_string(s, pos, n, num_bits);
  115. }
  116. template <typename CharT, typename Traits, typename Alloc>
  117. explicit
  118. dynamic_bitset(const std::basic_string<CharT, Traits, Alloc>& s,
  119. typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0)
  120. :m_bits(Allocator()),
  121. m_num_bits(0)
  122. {
  123. init_from_string(s, pos, (std::basic_string<CharT, Traits, Alloc>::npos),
  124. npos);
  125. }
  126. // The first bit in *first is the least significant bit, and the
  127. // last bit in the block just before *last is the most significant bit.
  128. template <typename BlockInputIterator>
  129. dynamic_bitset(BlockInputIterator first, BlockInputIterator last,
  130. const Allocator& alloc = Allocator())
  131. :m_bits(alloc),
  132. m_num_bits(0)
  133. {
  134. using boost::detail::dynamic_bitset_impl::value_to_type;
  135. using boost::detail::dynamic_bitset_impl::is_numeric;
  136. const value_to_type<
  137. is_numeric<BlockInputIterator>::value> selector;
  138. dispatch_init(first, last, selector);
  139. }
  140. template <typename T>
  141. void dispatch_init(T num_bits, unsigned long value,
  142. detail::dynamic_bitset_impl::value_to_type<true>)
  143. {
  144. init_from_unsigned_long(static_cast<size_type>(num_bits), value);
  145. }
  146. template <typename T>
  147. void dispatch_init(T first, T last,
  148. detail::dynamic_bitset_impl::value_to_type<false>)
  149. {
  150. init_from_block_range(first, last);
  151. }
  152. template <typename BlockIter>
  153. void init_from_block_range(BlockIter first, BlockIter last)
  154. {
  155. assert(m_bits.size() == 0);
  156. m_bits.insert(m_bits.end(), first, last);
  157. m_num_bits = m_bits.size() * bits_per_block;
  158. }
  159. // copy constructor
  160. dynamic_bitset(const dynamic_bitset& b);
  161. ~dynamic_bitset();
  162. void swap(dynamic_bitset& b);
  163. dynamic_bitset& operator=(const dynamic_bitset& b);
  164. allocator_type get_allocator() const;
  165. // size changing operations
  166. void resize(size_type num_bits, bool value = false);
  167. void clear();
  168. void push_back(bool bit);
  169. void append(Block block);
  170. template <typename BlockInputIterator>
  171. void m_append(BlockInputIterator first, BlockInputIterator last, std::input_iterator_tag)
  172. {
  173. std::vector<Block, Allocator> v(first, last);
  174. m_append(v.begin(), v.end(), std::random_access_iterator_tag());
  175. }
  176. template <typename BlockInputIterator>
  177. void m_append(BlockInputIterator first, BlockInputIterator last, std::forward_iterator_tag)
  178. {
  179. assert(first != last);
  180. block_width_type r = count_extra_bits();
  181. std::size_t d = boost::detail::distance(first, last);
  182. m_bits.reserve(num_blocks() + d);
  183. if (r == 0) {
  184. for( ; first != last; ++first)
  185. m_bits.push_back(*first); // could use vector<>::insert()
  186. }
  187. else {
  188. m_highest_block() |= (*first << r);
  189. do {
  190. Block b = *first >> (bits_per_block - r);
  191. ++first;
  192. m_bits.push_back(b | (first==last? 0 : *first << r));
  193. } while (first != last);
  194. }
  195. m_num_bits += bits_per_block * d;
  196. }
  197. template <typename BlockInputIterator>
  198. void append(BlockInputIterator first, BlockInputIterator last) // strong guarantee
  199. {
  200. if (first != last) {
  201. typename detail::iterator_traits<BlockInputIterator>::iterator_category cat;
  202. m_append(first, last, cat);
  203. }
  204. }
  205. // bitset operations
  206. dynamic_bitset& operator&=(const dynamic_bitset& b);
  207. dynamic_bitset& operator|=(const dynamic_bitset& b);
  208. dynamic_bitset& operator^=(const dynamic_bitset& b);
  209. dynamic_bitset& operator-=(const dynamic_bitset& b);
  210. dynamic_bitset& operator<<=(size_type n);
  211. dynamic_bitset& operator>>=(size_type n);
  212. dynamic_bitset operator<<(size_type n) const;
  213. dynamic_bitset operator>>(size_type n) const;
  214. // basic bit operations
  215. dynamic_bitset& set(size_type n, bool val = true);
  216. dynamic_bitset& set();
  217. dynamic_bitset& reset(size_type n);
  218. dynamic_bitset& reset();
  219. dynamic_bitset& flip(size_type n);
  220. dynamic_bitset& flip();
  221. bool test(size_type n) const;
  222. bool any() const;
  223. bool none() const;
  224. dynamic_bitset operator~() const;
  225. size_type count() const;
  226. // subscript
  227. reference operator[](size_type pos) {
  228. return reference(m_bits[block_index(pos)], bit_index(pos));
  229. }
  230. bool operator[](size_type pos) const { return test(pos); }
  231. unsigned long to_ulong() const;
  232. size_type size() const;
  233. size_type num_blocks() const;
  234. size_type max_size() const;
  235. bool empty() const;
  236. bool is_subset_of(const dynamic_bitset& a) const;
  237. bool is_proper_subset_of(const dynamic_bitset& a) const;
  238. bool intersects(const dynamic_bitset & a) const;
  239. // lookup
  240. size_type find_first() const;
  241. size_type find_next(size_type pos) const;
  242. #if !defined BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
  243. // lexicographical comparison
  244. template <typename B, typename A>
  245. friend bool operator==(const dynamic_bitset<B, A>& a,
  246. const dynamic_bitset<B, A>& b);
  247. template <typename B, typename A>
  248. friend bool operator<(const dynamic_bitset<B, A>& a,
  249. const dynamic_bitset<B, A>& b);
  250. template <typename B, typename A, typename BlockOutputIterator>
  251. friend void to_block_range(const dynamic_bitset<B, A>& b,
  252. BlockOutputIterator result);
  253. template <typename BlockIterator, typename B, typename A>
  254. friend void from_block_range(BlockIterator first, BlockIterator last,
  255. dynamic_bitset<B, A>& result);
  256. template <typename CharT, typename Traits, typename B, typename A>
  257. friend std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is,
  258. dynamic_bitset<B, A>& b);
  259. template <typename B, typename A, typename stringT>
  260. friend void to_string_helper(const dynamic_bitset<B, A> & b, stringT & s, bool dump_all);
  261. #endif
  262. private:
  263. BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits<unsigned long>::digits);
  264. typedef std::vector<block_type, allocator_type> buffer_type;
  265. void m_zero_unused_bits();
  266. bool m_check_invariants() const;
  267. size_type m_do_find_from(size_type first_block) const;
  268. block_width_type count_extra_bits() const { return bit_index(size()); }
  269. static size_type block_index(size_type pos) { return pos / bits_per_block; }
  270. static block_width_type bit_index(size_type pos) { return static_cast<block_width_type>(pos % bits_per_block); }
  271. static Block bit_mask(size_type pos) { return Block(1) << bit_index(pos); }
  272. template <typename CharT, typename Traits, typename Alloc>
  273. void init_from_string(const std::basic_string<CharT, Traits, Alloc>& s,
  274. typename std::basic_string<CharT, Traits, Alloc>::size_type pos,
  275. typename std::basic_string<CharT, Traits, Alloc>::size_type n,
  276. size_type num_bits)
  277. {
  278. assert(pos <= s.size());
  279. typedef typename std::basic_string<CharT, Traits, Alloc> StrT;
  280. typedef typename StrT::traits_type Tr;
  281. const typename StrT::size_type rlen = (std::min)(n, s.size() - pos);
  282. const size_type sz = ( num_bits != npos? num_bits : rlen);
  283. m_bits.resize(calc_num_blocks(sz));
  284. m_num_bits = sz;
  285. BOOST_DYNAMIC_BITSET_CTYPE_FACET(CharT, fac, std::locale());
  286. const CharT one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
  287. const size_type m = num_bits < rlen ? num_bits : rlen;
  288. typename StrT::size_type i = 0;
  289. for( ; i < m; ++i) {
  290. const CharT c = s[(pos + m - 1) - i];
  291. assert( Tr::eq(c, one)
  292. || Tr::eq(c, BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0')) );
  293. if (Tr::eq(c, one))
  294. set(i);
  295. }
  296. }
  297. void init_from_unsigned_long(size_type num_bits,
  298. unsigned long value/*,
  299. const Allocator& alloc*/)
  300. {
  301. assert(m_bits.size() == 0);
  302. m_bits.resize(calc_num_blocks(num_bits));
  303. m_num_bits = num_bits;
  304. typedef unsigned long num_type;
  305. typedef boost::detail::dynamic_bitset_impl
  306. ::shifter<num_type, bits_per_block, ulong_width> shifter;
  307. //if (num_bits == 0)
  308. // return;
  309. // zero out all bits at pos >= num_bits, if any;
  310. // note that: num_bits == 0 implies value == 0
  311. if (num_bits < static_cast<size_type>(ulong_width)) {
  312. const num_type mask = (num_type(1) << num_bits) - 1;
  313. value &= mask;
  314. }
  315. typename buffer_type::iterator it = m_bits.begin();
  316. for( ; value; shifter::left_shift(value), ++it) {
  317. *it = static_cast<block_type>(value);
  318. }
  319. }
  320. BOOST_DYNAMIC_BITSET_PRIVATE:
  321. bool m_unchecked_test(size_type pos) const;
  322. static size_type calc_num_blocks(size_type num_bits);
  323. Block& m_highest_block();
  324. const Block& m_highest_block() const;
  325. buffer_type m_bits;
  326. size_type m_num_bits;
  327. class bit_appender;
  328. friend class bit_appender;
  329. class bit_appender {
  330. // helper for stream >>
  331. // Supplies to the lack of an efficient append at the less
  332. // significant end: bits are actually appended "at left" but
  333. // rearranged in the destructor. From the perspective of
  334. // client code everything works *as if* dynamic_bitset<> had
  335. // an append_at_right() function (eventually throwing the same
  336. // exceptions as push_back) except that the function is in fact
  337. // called bit_appender::do_append().
  338. //
  339. dynamic_bitset & bs;
  340. size_type n;
  341. Block mask;
  342. Block * current;
  343. // not implemented
  344. bit_appender(const bit_appender &);
  345. bit_appender & operator=(const bit_appender &);
  346. public:
  347. bit_appender(dynamic_bitset & r) : bs(r), n(0), mask(0), current(0) {}
  348. ~bit_appender() {
  349. // reverse the order of blocks, shift
  350. // if needed, and then resize
  351. //
  352. std::reverse(bs.m_bits.begin(), bs.m_bits.end());
  353. const block_width_type offs = bit_index(n);
  354. if (offs)
  355. bs >>= (bits_per_block - offs);
  356. bs.resize(n); // doesn't enlarge, so can't throw
  357. assert(bs.m_check_invariants());
  358. }
  359. inline void do_append(bool value) {
  360. if (mask == 0) {
  361. bs.append(Block(0));
  362. current = &bs.m_highest_block();
  363. mask = Block(1) << (bits_per_block - 1);
  364. }
  365. if(value)
  366. *current |= mask;
  367. mask /= 2;
  368. ++n;
  369. }
  370. size_type get_count() const { return n; }
  371. };
  372. };
  373. #if !defined BOOST_NO_INCLASS_MEMBER_INITIALIZATION
  374. template <typename Block, typename Allocator>
  375. const typename dynamic_bitset<Block, Allocator>::block_width_type
  376. dynamic_bitset<Block, Allocator>::bits_per_block;
  377. template <typename Block, typename Allocator>
  378. const typename dynamic_bitset<Block, Allocator>::size_type
  379. dynamic_bitset<Block, Allocator>::npos;
  380. template <typename Block, typename Allocator>
  381. const typename dynamic_bitset<Block, Allocator>::block_width_type
  382. dynamic_bitset<Block, Allocator>::ulong_width;
  383. #endif
  384. // Global Functions:
  385. // comparison
  386. template <typename Block, typename Allocator>
  387. bool operator!=(const dynamic_bitset<Block, Allocator>& a,
  388. const dynamic_bitset<Block, Allocator>& b);
  389. template <typename Block, typename Allocator>
  390. bool operator<=(const dynamic_bitset<Block, Allocator>& a,
  391. const dynamic_bitset<Block, Allocator>& b);
  392. template <typename Block, typename Allocator>
  393. bool operator>(const dynamic_bitset<Block, Allocator>& a,
  394. const dynamic_bitset<Block, Allocator>& b);
  395. template <typename Block, typename Allocator>
  396. bool operator>=(const dynamic_bitset<Block, Allocator>& a,
  397. const dynamic_bitset<Block, Allocator>& b);
  398. // stream operators
  399. #ifdef BOOST_OLD_IOSTREAMS
  400. template <typename Block, typename Allocator>
  401. std::ostream& operator<<(std::ostream& os,
  402. const dynamic_bitset<Block, Allocator>& b);
  403. template <typename Block, typename Allocator>
  404. std::istream& operator>>(std::istream& is, dynamic_bitset<Block,Allocator>& b);
  405. #else
  406. template <typename CharT, typename Traits, typename Block, typename Allocator>
  407. std::basic_ostream<CharT, Traits>&
  408. operator<<(std::basic_ostream<CharT, Traits>& os,
  409. const dynamic_bitset<Block, Allocator>& b);
  410. template <typename CharT, typename Traits, typename Block, typename Allocator>
  411. std::basic_istream<CharT, Traits>&
  412. operator>>(std::basic_istream<CharT, Traits>& is,
  413. dynamic_bitset<Block, Allocator>& b);
  414. #endif
  415. // bitset operations
  416. template <typename Block, typename Allocator>
  417. dynamic_bitset<Block, Allocator>
  418. operator&(const dynamic_bitset<Block, Allocator>& b1,
  419. const dynamic_bitset<Block, Allocator>& b2);
  420. template <typename Block, typename Allocator>
  421. dynamic_bitset<Block, Allocator>
  422. operator|(const dynamic_bitset<Block, Allocator>& b1,
  423. const dynamic_bitset<Block, Allocator>& b2);
  424. template <typename Block, typename Allocator>
  425. dynamic_bitset<Block, Allocator>
  426. operator^(const dynamic_bitset<Block, Allocator>& b1,
  427. const dynamic_bitset<Block, Allocator>& b2);
  428. template <typename Block, typename Allocator>
  429. dynamic_bitset<Block, Allocator>
  430. operator-(const dynamic_bitset<Block, Allocator>& b1,
  431. const dynamic_bitset<Block, Allocator>& b2);
  432. // namespace scope swap
  433. template<typename Block, typename Allocator>
  434. void swap(dynamic_bitset<Block, Allocator>& b1,
  435. dynamic_bitset<Block, Allocator>& b2);
  436. template <typename Block, typename Allocator, typename stringT>
  437. void
  438. to_string(const dynamic_bitset<Block, Allocator>& b, stringT & s);
  439. template <typename Block, typename Allocator, typename BlockOutputIterator>
  440. void
  441. to_block_range(const dynamic_bitset<Block, Allocator>& b,
  442. BlockOutputIterator result);
  443. template <typename BlockIterator, typename B, typename A>
  444. inline void
  445. from_block_range(BlockIterator first, BlockIterator last,
  446. dynamic_bitset<B, A>& result)
  447. {
  448. // PRE: distance(first, last) <= numblocks()
  449. std::copy (first, last, result.m_bits.begin());
  450. }
  451. //=============================================================================
  452. // dynamic_bitset implementation
  453. //-----------------------------------------------------------------------------
  454. // constructors, etc.
  455. template <typename Block, typename Allocator>
  456. dynamic_bitset<Block, Allocator>::dynamic_bitset(const Allocator& alloc)
  457. : m_bits(alloc), m_num_bits(0)
  458. {
  459. }
  460. template <typename Block, typename Allocator>
  461. dynamic_bitset<Block, Allocator>::
  462. dynamic_bitset(size_type num_bits, unsigned long value, const Allocator& alloc)
  463. : m_bits(alloc),
  464. m_num_bits(0)
  465. {
  466. init_from_unsigned_long(num_bits, value);
  467. }
  468. // copy constructor
  469. template <typename Block, typename Allocator>
  470. inline dynamic_bitset<Block, Allocator>::
  471. dynamic_bitset(const dynamic_bitset& b)
  472. : m_bits(b.m_bits), m_num_bits(b.m_num_bits)
  473. {
  474. }
  475. template <typename Block, typename Allocator>
  476. inline dynamic_bitset<Block, Allocator>::
  477. ~dynamic_bitset()
  478. {
  479. assert(m_check_invariants());
  480. }
  481. template <typename Block, typename Allocator>
  482. inline void dynamic_bitset<Block, Allocator>::
  483. swap(dynamic_bitset<Block, Allocator>& b) // no throw
  484. {
  485. std::swap(m_bits, b.m_bits);
  486. std::swap(m_num_bits, b.m_num_bits);
  487. }
  488. template <typename Block, typename Allocator>
  489. dynamic_bitset<Block, Allocator>& dynamic_bitset<Block, Allocator>::
  490. operator=(const dynamic_bitset<Block, Allocator>& b)
  491. {
  492. m_bits = b.m_bits;
  493. m_num_bits = b.m_num_bits;
  494. return *this;
  495. }
  496. template <typename Block, typename Allocator>
  497. inline typename dynamic_bitset<Block, Allocator>::allocator_type
  498. dynamic_bitset<Block, Allocator>::get_allocator() const
  499. {
  500. return m_bits.get_allocator();
  501. }
  502. //-----------------------------------------------------------------------------
  503. // size changing operations
  504. template <typename Block, typename Allocator>
  505. void dynamic_bitset<Block, Allocator>::
  506. resize(size_type num_bits, bool value) // strong guarantee
  507. {
  508. const size_type old_num_blocks = num_blocks();
  509. const size_type required_blocks = calc_num_blocks(num_bits);
  510. const block_type v = value? ~Block(0) : Block(0);
  511. if (required_blocks != old_num_blocks) {
  512. m_bits.resize(required_blocks, v); // s.g. (copy)
  513. }
  514. // At this point:
  515. //
  516. // - if the buffer was shrunk, we have nothing more to do,
  517. // except a call to m_zero_unused_bits()
  518. //
  519. // - if it was enlarged, all the (used) bits in the new blocks have
  520. // the correct value, but we have not yet touched those bits, if
  521. // any, that were 'unused bits' before enlarging: if value == true,
  522. // they must be set.
  523. if (value && (num_bits > m_num_bits)) {
  524. const block_width_type extra_bits = count_extra_bits();
  525. if (extra_bits) {
  526. assert(old_num_blocks >= 1 && old_num_blocks <= m_bits.size());
  527. // Set them.
  528. m_bits[old_num_blocks - 1] |= (v << extra_bits);
  529. }
  530. }
  531. m_num_bits = num_bits;
  532. m_zero_unused_bits();
  533. }
  534. template <typename Block, typename Allocator>
  535. void dynamic_bitset<Block, Allocator>::
  536. clear() // no throw
  537. {
  538. m_bits.clear();
  539. m_num_bits = 0;
  540. }
  541. template <typename Block, typename Allocator>
  542. void dynamic_bitset<Block, Allocator>::
  543. push_back(bool bit)
  544. {
  545. const size_type sz = size();
  546. resize(sz + 1);
  547. set(sz, bit);
  548. }
  549. template <typename Block, typename Allocator>
  550. void dynamic_bitset<Block, Allocator>::
  551. append(Block value) // strong guarantee
  552. {
  553. const block_width_type r = count_extra_bits();
  554. if (r == 0) {
  555. // the buffer is empty, or all blocks are filled
  556. m_bits.push_back(value);
  557. }
  558. else {
  559. m_bits.push_back(value >> (bits_per_block - r));
  560. m_bits[m_bits.size() - 2] |= (value << r); // m_bits.size() >= 2
  561. }
  562. m_num_bits += bits_per_block;
  563. assert(m_check_invariants());
  564. }
  565. //-----------------------------------------------------------------------------
  566. // bitset operations
  567. template <typename Block, typename Allocator>
  568. dynamic_bitset<Block, Allocator>&
  569. dynamic_bitset<Block, Allocator>::operator&=(const dynamic_bitset& rhs)
  570. {
  571. assert(size() == rhs.size());
  572. for (size_type i = 0; i < num_blocks(); ++i)
  573. m_bits[i] &= rhs.m_bits[i];
  574. return *this;
  575. }
  576. template <typename Block, typename Allocator>
  577. dynamic_bitset<Block, Allocator>&
  578. dynamic_bitset<Block, Allocator>::operator|=(const dynamic_bitset& rhs)
  579. {
  580. assert(size() == rhs.size());
  581. for (size_type i = 0; i < num_blocks(); ++i)
  582. m_bits[i] |= rhs.m_bits[i];
  583. //m_zero_unused_bits();
  584. return *this;
  585. }
  586. template <typename Block, typename Allocator>
  587. dynamic_bitset<Block, Allocator>&
  588. dynamic_bitset<Block, Allocator>::operator^=(const dynamic_bitset& rhs)
  589. {
  590. assert(size() == rhs.size());
  591. for (size_type i = 0; i < this->num_blocks(); ++i)
  592. m_bits[i] ^= rhs.m_bits[i];
  593. //m_zero_unused_bits();
  594. return *this;
  595. }
  596. template <typename Block, typename Allocator>
  597. dynamic_bitset<Block, Allocator>&
  598. dynamic_bitset<Block, Allocator>::operator-=(const dynamic_bitset& rhs)
  599. {
  600. assert(size() == rhs.size());
  601. for (size_type i = 0; i < num_blocks(); ++i)
  602. m_bits[i] &= ~rhs.m_bits[i];
  603. //m_zero_unused_bits();
  604. return *this;
  605. }
  606. //
  607. // NOTE:
  608. // Note that the 'if (r != 0)' is crucial to avoid undefined
  609. // behavior when the left hand operand of >> isn't promoted to a
  610. // wider type (because rs would be too large).
  611. //
  612. template <typename Block, typename Allocator>
  613. dynamic_bitset<Block, Allocator>&
  614. dynamic_bitset<Block, Allocator>::operator<<=(size_type n)
  615. {
  616. if (n >= m_num_bits)
  617. return reset();
  618. //else
  619. if (n > 0) {
  620. size_type const last = num_blocks() - 1; // num_blocks() is >= 1
  621. size_type const div = n / bits_per_block; // div is <= last
  622. block_width_type const r = bit_index(n);
  623. block_type * const b = &m_bits[0];
  624. if (r != 0) {
  625. block_width_type const rs = bits_per_block - r;
  626. for (size_type i = last-div; i>0; --i) {
  627. b[i+div] = (b[i] << r) | (b[i-1] >> rs);
  628. }
  629. b[div] = b[0] << r;
  630. }
  631. else {
  632. for (size_type i = last-div; i>0; --i) {
  633. b[i+div] = b[i];
  634. }
  635. b[div] = b[0];
  636. }
  637. // zero out div blocks at the less significant end
  638. std::fill_n(b, div, static_cast<block_type>(0));
  639. // zero out any 1 bit that flowed into the unused part
  640. m_zero_unused_bits(); // thanks to Lester Gong
  641. }
  642. return *this;
  643. }
  644. //
  645. // NOTE:
  646. // see the comments to operator <<=
  647. //
  648. template <typename B, typename A>
  649. dynamic_bitset<B, A> & dynamic_bitset<B, A>::operator>>=(size_type n) {
  650. if (n >= m_num_bits) {
  651. return reset();
  652. }
  653. //else
  654. if (n>0) {
  655. size_type const last = num_blocks() - 1; // num_blocks() is >= 1
  656. size_type const div = n / bits_per_block; // div is <= last
  657. block_width_type const r = bit_index(n);
  658. block_type * const b = &m_bits[0];
  659. if (r != 0) {
  660. block_width_type const ls = bits_per_block - r;
  661. for (size_type i = div; i < last; ++i) {
  662. b[i-div] = (b[i] >> r) | (b[i+1] << ls);
  663. }
  664. // r bits go to zero
  665. b[last-div] = b[last] >> r;
  666. }
  667. else {
  668. for (size_type i = div; i <= last; ++i) {
  669. b[i-div] = b[i];
  670. }
  671. // note the '<=': the last iteration 'absorbs'
  672. // b[last-div] = b[last] >> 0;
  673. }
  674. // div blocks are zero filled at the most significant end
  675. std::fill_n(b + (num_blocks()-div), div, static_cast<block_type>(0));
  676. }
  677. return *this;
  678. }
  679. template <typename Block, typename Allocator>
  680. dynamic_bitset<Block, Allocator>
  681. dynamic_bitset<Block, Allocator>::operator<<(size_type n) const
  682. {
  683. dynamic_bitset r(*this);
  684. return r <<= n;
  685. }
  686. template <typename Block, typename Allocator>
  687. dynamic_bitset<Block, Allocator>
  688. dynamic_bitset<Block, Allocator>::operator>>(size_type n) const
  689. {
  690. dynamic_bitset r(*this);
  691. return r >>= n;
  692. }
  693. //-----------------------------------------------------------------------------
  694. // basic bit operations
  695. template <typename Block, typename Allocator>
  696. dynamic_bitset<Block, Allocator>&
  697. dynamic_bitset<Block, Allocator>::set(size_type pos, bool val)
  698. {
  699. assert(pos < m_num_bits);
  700. if (val)
  701. m_bits[block_index(pos)] |= bit_mask(pos);
  702. else
  703. reset(pos);
  704. return *this;
  705. }
  706. template <typename Block, typename Allocator>
  707. dynamic_bitset<Block, Allocator>&
  708. dynamic_bitset<Block, Allocator>::set()
  709. {
  710. std::fill(m_bits.begin(), m_bits.end(), ~Block(0));
  711. m_zero_unused_bits();
  712. return *this;
  713. }
  714. template <typename Block, typename Allocator>
  715. dynamic_bitset<Block, Allocator>&
  716. dynamic_bitset<Block, Allocator>::reset(size_type pos)
  717. {
  718. assert(pos < m_num_bits);
  719. #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
  720. // CodeWarrior 8 generates incorrect code when the &=~ is compiled,
  721. // use the |^ variation instead.. <grafik>
  722. m_bits[block_index(pos)] |= bit_mask(pos);
  723. m_bits[block_index(pos)] ^= bit_mask(pos);
  724. #else
  725. m_bits[block_index(pos)] &= ~bit_mask(pos);
  726. #endif
  727. return *this;
  728. }
  729. template <typename Block, typename Allocator>
  730. dynamic_bitset<Block, Allocator>&
  731. dynamic_bitset<Block, Allocator>::reset()
  732. {
  733. std::fill(m_bits.begin(), m_bits.end(), Block(0));
  734. return *this;
  735. }
  736. template <typename Block, typename Allocator>
  737. dynamic_bitset<Block, Allocator>&
  738. dynamic_bitset<Block, Allocator>::flip(size_type pos)
  739. {
  740. assert(pos < m_num_bits);
  741. m_bits[block_index(pos)] ^= bit_mask(pos);
  742. return *this;
  743. }
  744. template <typename Block, typename Allocator>
  745. dynamic_bitset<Block, Allocator>&
  746. dynamic_bitset<Block, Allocator>::flip()
  747. {
  748. for (size_type i = 0; i < num_blocks(); ++i)
  749. m_bits[i] = ~m_bits[i];
  750. m_zero_unused_bits();
  751. return *this;
  752. }
  753. template <typename Block, typename Allocator>
  754. bool dynamic_bitset<Block, Allocator>::m_unchecked_test(size_type pos) const
  755. {
  756. return (m_bits[block_index(pos)] & bit_mask(pos)) != 0;
  757. }
  758. template <typename Block, typename Allocator>
  759. bool dynamic_bitset<Block, Allocator>::test(size_type pos) const
  760. {
  761. assert(pos < m_num_bits);
  762. return m_unchecked_test(pos);
  763. }
  764. template <typename Block, typename Allocator>
  765. bool dynamic_bitset<Block, Allocator>::any() const
  766. {
  767. for (size_type i = 0; i < num_blocks(); ++i)
  768. if (m_bits[i])
  769. return true;
  770. return false;
  771. }
  772. template <typename Block, typename Allocator>
  773. inline bool dynamic_bitset<Block, Allocator>::none() const
  774. {
  775. return !any();
  776. }
  777. template <typename Block, typename Allocator>
  778. dynamic_bitset<Block, Allocator>
  779. dynamic_bitset<Block, Allocator>::operator~() const
  780. {
  781. dynamic_bitset b(*this);
  782. b.flip();
  783. return b;
  784. }
  785. template <typename Block, typename Allocator>
  786. typename dynamic_bitset<Block, Allocator>::size_type
  787. dynamic_bitset<Block, Allocator>::count() const
  788. {
  789. using detail::dynamic_bitset_impl::table_width;
  790. using detail::dynamic_bitset_impl::access_by_bytes;
  791. using detail::dynamic_bitset_impl::access_by_blocks;
  792. using detail::dynamic_bitset_impl::value_to_type;
  793. #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 3) && (__GNUC_PATCHLEVEL__ == 3)
  794. // NOTE: Explicit qualification of "bits_per_block"
  795. // breaks compilation on gcc 4.3.3
  796. enum { no_padding = bits_per_block == CHAR_BIT * sizeof(Block) };
  797. #else
  798. // NOTE: Explicitly qualifying "bits_per_block" to workaround
  799. // regressions of gcc 3.4.x
  800. enum { no_padding =
  801. dynamic_bitset<Block, Allocator>::bits_per_block
  802. == CHAR_BIT * sizeof(Block) };
  803. #endif
  804. enum { enough_table_width = table_width >= CHAR_BIT };
  805. enum { mode = (no_padding && enough_table_width)
  806. ? access_by_bytes
  807. : access_by_blocks };
  808. return do_count(m_bits.begin(), num_blocks(), Block(0),
  809. static_cast<value_to_type<(bool)mode> *>(0));
  810. }
  811. //-----------------------------------------------------------------------------
  812. // conversions
  813. template <typename B, typename A, typename stringT>
  814. void to_string_helper(const dynamic_bitset<B, A> & b, stringT & s,
  815. bool dump_all)
  816. {
  817. typedef typename stringT::traits_type Tr;
  818. typedef typename stringT::value_type Ch;
  819. BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, std::locale());
  820. const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
  821. const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
  822. // Note that this function may access (when
  823. // dump_all == true) bits beyond position size() - 1
  824. typedef typename dynamic_bitset<B, A>::size_type size_type;
  825. const size_type len = dump_all?
  826. dynamic_bitset<B, A>::bits_per_block * b.num_blocks():
  827. b.size();
  828. s.assign (len, zero);
  829. for (size_type i = 0; i < len; ++i) {
  830. if (b.m_unchecked_test(i))
  831. Tr::assign(s[len - 1 - i], one);
  832. }
  833. }
  834. // A comment similar to the one about the constructor from
  835. // basic_string can be done here. Thanks to James Kanze for
  836. // making me (Gennaro) realize this important separation of
  837. // concerns issue, as well as many things about i18n.
  838. //
  839. template <typename Block, typename Allocator, typename stringT>
  840. inline void
  841. to_string(const dynamic_bitset<Block, Allocator>& b, stringT& s)
  842. {
  843. to_string_helper(b, s, false);
  844. }
  845. // Differently from to_string this function dumps out
  846. // every bit of the internal representation (may be
  847. // useful for debugging purposes)
  848. //
  849. template <typename B, typename A, typename stringT>
  850. inline void
  851. dump_to_string(const dynamic_bitset<B, A>& b, stringT& s)
  852. {
  853. to_string_helper(b, s, true /* =dump_all*/);
  854. }
  855. template <typename Block, typename Allocator, typename BlockOutputIterator>
  856. inline void
  857. to_block_range(const dynamic_bitset<Block, Allocator>& b,
  858. BlockOutputIterator result)
  859. {
  860. // note how this copies *all* bits, including the
  861. // unused ones in the last block (which are zero)
  862. std::copy(b.m_bits.begin(), b.m_bits.end(), result);
  863. }
  864. template <typename Block, typename Allocator>
  865. unsigned long dynamic_bitset<Block, Allocator>::
  866. to_ulong() const
  867. {
  868. if (m_num_bits == 0)
  869. return 0; // convention
  870. // Check for overflows. This may be a performance burden on very
  871. // large bitsets but is required by the specification, sorry
  872. if (find_next(ulong_width - 1) != npos)
  873. throw std::overflow_error("boost::dynamic_bitset::to_ulong overflow");
  874. // Ok, from now on we can be sure there's no "on" bit
  875. // beyond the "allowed" positions
  876. typedef unsigned long result_type;
  877. const size_type maximum_size =
  878. (std::min)(m_num_bits, static_cast<size_type>(ulong_width));
  879. const size_type last_block = block_index( maximum_size - 1 );
  880. assert((last_block * bits_per_block) < static_cast<size_type>(ulong_width));
  881. result_type result = 0;
  882. for (size_type i = 0; i <= last_block; ++i) {
  883. const size_type offset = i * bits_per_block;
  884. result |= (static_cast<result_type>(m_bits[i]) << offset);
  885. }
  886. return result;
  887. }
  888. template <typename Block, typename Allocator>
  889. inline typename dynamic_bitset<Block, Allocator>::size_type
  890. dynamic_bitset<Block, Allocator>::size() const
  891. {
  892. return m_num_bits;
  893. }
  894. template <typename Block, typename Allocator>
  895. inline typename dynamic_bitset<Block, Allocator>::size_type
  896. dynamic_bitset<Block, Allocator>::num_blocks() const
  897. {
  898. return m_bits.size();
  899. }
  900. template <typename Block, typename Allocator>
  901. inline typename dynamic_bitset<Block, Allocator>::size_type
  902. dynamic_bitset<Block, Allocator>::max_size() const
  903. {
  904. // Semantics of vector<>::max_size() aren't very clear
  905. // (see lib issue 197) and many library implementations
  906. // simply return dummy values, _unrelated_ to the underlying
  907. // allocator.
  908. //
  909. // Given these problems, I was tempted to not provide this
  910. // function at all but the user could need it if he provides
  911. // his own allocator.
  912. //
  913. const size_type m = detail::dynamic_bitset_impl::
  914. vector_max_size_workaround(m_bits);
  915. return m <= (size_type(-1)/bits_per_block) ?
  916. m * bits_per_block :
  917. size_type(-1);
  918. }
  919. template <typename Block, typename Allocator>
  920. inline bool dynamic_bitset<Block, Allocator>::empty() const
  921. {
  922. return size() == 0;
  923. }
  924. template <typename Block, typename Allocator>
  925. bool dynamic_bitset<Block, Allocator>::
  926. is_subset_of(const dynamic_bitset<Block, Allocator>& a) const
  927. {
  928. assert(size() == a.size());
  929. for (size_type i = 0; i < num_blocks(); ++i)
  930. if (m_bits[i] & ~a.m_bits[i])
  931. return false;
  932. return true;
  933. }
  934. template <typename Block, typename Allocator>
  935. bool dynamic_bitset<Block, Allocator>::
  936. is_proper_subset_of(const dynamic_bitset<Block, Allocator>& a) const
  937. {
  938. assert(size() == a.size());
  939. assert(num_blocks() == a.num_blocks());
  940. bool proper = false;
  941. for (size_type i = 0; i < num_blocks(); ++i) {
  942. const Block & bt = m_bits[i];
  943. const Block & ba = a.m_bits[i];
  944. if (bt & ~ba)
  945. return false; // not a subset at all
  946. if (ba & ~bt)
  947. proper = true;
  948. }
  949. return proper;
  950. }
  951. template <typename Block, typename Allocator>
  952. bool dynamic_bitset<Block, Allocator>::intersects(const dynamic_bitset & b) const
  953. {
  954. size_type common_blocks = num_blocks() < b.num_blocks()
  955. ? num_blocks() : b.num_blocks();
  956. for(size_type i = 0; i < common_blocks; ++i) {
  957. if(m_bits[i] & b.m_bits[i])
  958. return true;
  959. }
  960. return false;
  961. }
  962. // --------------------------------
  963. // lookup
  964. // look for the first bit "on", starting
  965. // from the block with index first_block
  966. //
  967. template <typename Block, typename Allocator>
  968. typename dynamic_bitset<Block, Allocator>::size_type
  969. dynamic_bitset<Block, Allocator>::m_do_find_from(size_type first_block) const
  970. {
  971. size_type i = first_block;
  972. // skip null blocks
  973. while (i < num_blocks() && m_bits[i] == 0)
  974. ++i;
  975. if (i >= num_blocks())
  976. return npos; // not found
  977. return i * bits_per_block + boost::lowest_bit(m_bits[i]);
  978. }
  979. template <typename Block, typename Allocator>
  980. typename dynamic_bitset<Block, Allocator>::size_type
  981. dynamic_bitset<Block, Allocator>::find_first() const
  982. {
  983. return m_do_find_from(0);
  984. }
  985. template <typename Block, typename Allocator>
  986. typename dynamic_bitset<Block, Allocator>::size_type
  987. dynamic_bitset<Block, Allocator>::find_next(size_type pos) const
  988. {
  989. const size_type sz = size();
  990. if (pos >= (sz-1) || sz == 0)
  991. return npos;
  992. ++pos;
  993. const size_type blk = block_index(pos);
  994. const block_width_type ind = bit_index(pos);
  995. // mask out bits before pos
  996. const Block fore = m_bits[blk] & ( ~Block(0) << ind );
  997. return fore?
  998. blk * bits_per_block + lowest_bit(fore)
  999. :
  1000. m_do_find_from(blk + 1);
  1001. }
  1002. //-----------------------------------------------------------------------------
  1003. // comparison
  1004. template <typename Block, typename Allocator>
  1005. bool operator==(const dynamic_bitset<Block, Allocator>& a,
  1006. const dynamic_bitset<Block, Allocator>& b)
  1007. {
  1008. return (a.m_num_bits == b.m_num_bits)
  1009. && (a.m_bits == b.m_bits);
  1010. }
  1011. template <typename Block, typename Allocator>
  1012. inline bool operator!=(const dynamic_bitset<Block, Allocator>& a,
  1013. const dynamic_bitset<Block, Allocator>& b)
  1014. {
  1015. return !(a == b);
  1016. }
  1017. template <typename Block, typename Allocator>
  1018. bool operator<(const dynamic_bitset<Block, Allocator>& a,
  1019. const dynamic_bitset<Block, Allocator>& b)
  1020. {
  1021. assert(a.size() == b.size());
  1022. typedef typename dynamic_bitset<Block, Allocator>::size_type size_type;
  1023. //if (a.size() == 0)
  1024. // return false;
  1025. // Since we are storing the most significant bit
  1026. // at pos == size() - 1, we need to do the comparisons in reverse.
  1027. //
  1028. for (size_type ii = a.num_blocks(); ii > 0; --ii) {
  1029. size_type i = ii-1;
  1030. if (a.m_bits[i] < b.m_bits[i])
  1031. return true;
  1032. else if (a.m_bits[i] > b.m_bits[i])
  1033. return false;
  1034. }
  1035. return false;
  1036. }
  1037. template <typename Block, typename Allocator>
  1038. inline bool operator<=(const dynamic_bitset<Block, Allocator>& a,
  1039. const dynamic_bitset<Block, Allocator>& b)
  1040. {
  1041. return !(a > b);
  1042. }
  1043. template <typename Block, typename Allocator>
  1044. inline bool operator>(const dynamic_bitset<Block, Allocator>& a,
  1045. const dynamic_bitset<Block, Allocator>& b)
  1046. {
  1047. return b < a;
  1048. }
  1049. template <typename Block, typename Allocator>
  1050. inline bool operator>=(const dynamic_bitset<Block, Allocator>& a,
  1051. const dynamic_bitset<Block, Allocator>& b)
  1052. {
  1053. return !(a < b);
  1054. }
  1055. //-----------------------------------------------------------------------------
  1056. // stream operations
  1057. #ifdef BOOST_OLD_IOSTREAMS
  1058. template < typename Block, typename Alloc>
  1059. std::ostream&
  1060. operator<<(std::ostream& os, const dynamic_bitset<Block, Alloc>& b)
  1061. {
  1062. // NOTE: since this is aimed at "classic" iostreams, exception
  1063. // masks on the stream are not supported. The library that
  1064. // ships with gcc 2.95 has an exceptions() member function but
  1065. // nothing is actually implemented; not even the class ios::failure.
  1066. using namespace std;
  1067. const ios::iostate ok = ios::goodbit;
  1068. ios::iostate err = ok;
  1069. if (os.opfx()) {
  1070. //try
  1071. typedef typename dynamic_bitset<Block, Alloc>::size_type bitsetsize_type;
  1072. const bitsetsize_type sz = b.size();
  1073. std::streambuf * buf = os.rdbuf();
  1074. size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0)
  1075. || (bitsetsize_type) os.width() <= sz? 0 : os.width() - sz;
  1076. const char fill_char = os.fill();
  1077. const ios::fmtflags adjustfield = os.flags() & ios::adjustfield;
  1078. // if needed fill at left; pad is decresed along the way
  1079. if (adjustfield != ios::left) {
  1080. for (; 0 < npad; --npad)
  1081. if (fill_char != buf->sputc(fill_char)) {
  1082. err |= ios::failbit;
  1083. break;
  1084. }
  1085. }
  1086. if (err == ok) {
  1087. // output the bitset
  1088. for (bitsetsize_type i = b.size(); 0 < i; --i) {
  1089. const char dig = b.test(i-1)? '1' : '0';
  1090. if (EOF == buf->sputc(dig)) {
  1091. err |= ios::failbit;
  1092. break;
  1093. }
  1094. }
  1095. }
  1096. if (err == ok) {
  1097. // if needed fill at right
  1098. for (; 0 < npad; --npad) {
  1099. if (fill_char != buf->sputc(fill_char)) {
  1100. err |= ios::failbit;
  1101. break;
  1102. }
  1103. }
  1104. }
  1105. os.osfx();
  1106. os.width(0);
  1107. } // if opfx
  1108. if(err != ok)
  1109. os.setstate(err); // assume this does NOT throw
  1110. return os;
  1111. }
  1112. #else
  1113. template <typename Ch, typename Tr, typename Block, typename Alloc>
  1114. std::basic_ostream<Ch, Tr>&
  1115. operator<<(std::basic_ostream<Ch, Tr>& os,
  1116. const dynamic_bitset<Block, Alloc>& b)
  1117. {
  1118. using namespace std;
  1119. const ios_base::iostate ok = ios_base::goodbit;
  1120. ios_base::iostate err = ok;
  1121. typename basic_ostream<Ch, Tr>::sentry cerberos(os);
  1122. if (cerberos) {
  1123. BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, os.getloc());
  1124. const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
  1125. const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
  1126. try {
  1127. typedef typename dynamic_bitset<Block, Alloc>::size_type bitsetsize_type;
  1128. typedef basic_streambuf<Ch, Tr> buffer_type;
  1129. buffer_type * buf = os.rdbuf();
  1130. size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0)
  1131. || (bitsetsize_type) os.width() <= b.size()? 0 : os.width() - b.size();
  1132. const Ch fill_char = os.fill();
  1133. const ios_base::fmtflags adjustfield = os.flags() & ios_base::adjustfield;
  1134. // if needed fill at left; pad is decresed along the way
  1135. if (adjustfield != ios_base::left) {
  1136. for (; 0 < npad; --npad)
  1137. if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) {
  1138. err |= ios_base::failbit;
  1139. break;
  1140. }
  1141. }
  1142. if (err == ok) {
  1143. // output the bitset
  1144. for (bitsetsize_type i = b.size(); 0 < i; --i) {
  1145. typename buffer_type::int_type
  1146. ret = buf->sputc(b.test(i-1)? one : zero);
  1147. if (Tr::eq_int_type(Tr::eof(), ret)) {
  1148. err |= ios_base::failbit;
  1149. break;
  1150. }
  1151. }
  1152. }
  1153. if (err == ok) {
  1154. // if needed fill at right
  1155. for (; 0 < npad; --npad) {
  1156. if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) {
  1157. err |= ios_base::failbit;
  1158. break;
  1159. }
  1160. }
  1161. }
  1162. os.width(0);
  1163. } catch (...) { // see std 27.6.1.1/4
  1164. bool rethrow = false;
  1165. try { os.setstate(ios_base::failbit); } catch (...) { rethrow = true; }
  1166. if (rethrow)
  1167. throw;
  1168. }
  1169. }
  1170. if(err != ok)
  1171. os.setstate(err); // may throw exception
  1172. return os;
  1173. }
  1174. #endif
  1175. #ifdef BOOST_OLD_IOSTREAMS
  1176. // A sentry-like class that calls isfx in its destructor.
  1177. // "Necessary" because bit_appender::do_append may throw.
  1178. class pseudo_sentry {
  1179. std::istream & m_r;
  1180. const bool m_ok;
  1181. public:
  1182. explicit pseudo_sentry(std::istream & r) : m_r(r), m_ok(r.ipfx(0)) { }
  1183. ~pseudo_sentry() { m_r.isfx(); }
  1184. operator bool() const { return m_ok; }
  1185. };
  1186. template <typename Block, typename Alloc>
  1187. std::istream&
  1188. operator>>(std::istream& is, dynamic_bitset<Block, Alloc>& b)
  1189. {
  1190. // Extractor for classic IO streams (libstdc++ < 3.0)
  1191. // ----------------------------------------------------//
  1192. // It's assumed that the stream buffer functions, and
  1193. // the stream's setstate() _cannot_ throw.
  1194. typedef dynamic_bitset<Block, Alloc> bitset_type;
  1195. typedef typename bitset_type::size_type size_type;
  1196. std::ios::iostate err = std::ios::goodbit;
  1197. pseudo_sentry cerberos(is); // skips whitespaces
  1198. if(cerberos) {
  1199. b.clear();
  1200. const std::streamsize w = is.width();
  1201. const size_type limit = w > 0 && static_cast<size_type>(w) < b.max_size()
  1202. ? w : b.max_size();
  1203. typename bitset_type::bit_appender appender(b);
  1204. std::streambuf * buf = is.rdbuf();
  1205. for(int c = buf->sgetc(); appender.get_count() < limit; c = buf->snextc() ) {
  1206. if (c == EOF) {
  1207. err |= std::ios::eofbit;
  1208. break;
  1209. }
  1210. else if (char(c) != '0' && char(c) != '1')
  1211. break; // non digit character
  1212. else {
  1213. try {
  1214. appender.do_append(char(c) == '1');
  1215. }
  1216. catch(...) {
  1217. is.setstate(std::ios::failbit); // assume this can't throw
  1218. throw;
  1219. }
  1220. }
  1221. } // for
  1222. }
  1223. is.width(0);
  1224. if (b.size() == 0)
  1225. err |= std::ios::failbit;
  1226. if (err != std::ios::goodbit)
  1227. is.setstate (err); // may throw
  1228. return is;
  1229. }
  1230. #else // BOOST_OLD_IOSTREAMS
  1231. template <typename Ch, typename Tr, typename Block, typename Alloc>
  1232. std::basic_istream<Ch, Tr>&
  1233. operator>>(std::basic_istream<Ch, Tr>& is, dynamic_bitset<Block, Alloc>& b)
  1234. {
  1235. using namespace std;
  1236. typedef dynamic_bitset<Block, Alloc> bitset_type;
  1237. typedef typename bitset_type::size_type size_type;
  1238. const streamsize w = is.width();
  1239. const size_type limit = 0 < w && static_cast<size_type>(w) < b.max_size()?
  1240. w : b.max_size();
  1241. ios_base::iostate err = ios_base::goodbit;
  1242. typename basic_istream<Ch, Tr>::sentry cerberos(is); // skips whitespaces
  1243. if(cerberos) {
  1244. // in accordance with prop. resol. of lib DR 303 [last checked 4 Feb 2004]
  1245. BOOST_DYNAMIC_BITSET_CTYPE_FACET(Ch, fac, is.getloc());
  1246. const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
  1247. const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
  1248. b.clear();
  1249. try {
  1250. typename bitset_type::bit_appender appender(b);
  1251. basic_streambuf <Ch, Tr> * buf = is.rdbuf();
  1252. typename Tr::int_type c = buf->sgetc();
  1253. for( ; appender.get_count() < limit; c = buf->snextc() ) {
  1254. if (Tr::eq_int_type(Tr::eof(), c)) {
  1255. err |= ios_base::eofbit;
  1256. break;
  1257. }
  1258. else {
  1259. const Ch to_c = Tr::to_char_type(c);
  1260. const bool is_one = Tr::eq(to_c, one);
  1261. if (!is_one && !Tr::eq(to_c, zero))
  1262. break; // non digit character
  1263. appender.do_append(is_one);
  1264. }
  1265. } // for
  1266. }
  1267. catch (...) {
  1268. // catches from stream buf, or from vector:
  1269. //
  1270. // bits_stored bits have been extracted and stored, and
  1271. // either no further character is extractable or we can't
  1272. // append to the underlying vector (out of memory)
  1273. bool rethrow = false; // see std 27.6.1.1/4
  1274. try { is.setstate(ios_base::badbit); }
  1275. catch(...) { rethrow = true; }
  1276. if (rethrow)
  1277. throw;
  1278. }
  1279. }
  1280. is.width(0);
  1281. if (b.size() == 0 /*|| !cerberos*/)
  1282. err |= ios_base::failbit;
  1283. if (err != ios_base::goodbit)
  1284. is.setstate (err); // may throw
  1285. return is;
  1286. }
  1287. #endif
  1288. //-----------------------------------------------------------------------------
  1289. // bitset operations
  1290. template <typename Block, typename Allocator>
  1291. dynamic_bitset<Block, Allocator>
  1292. operator&(const dynamic_bitset<Block, Allocator>& x,
  1293. const dynamic_bitset<Block, Allocator>& y)
  1294. {
  1295. dynamic_bitset<Block, Allocator> b(x);
  1296. return b &= y;
  1297. }
  1298. template <typename Block, typename Allocator>
  1299. dynamic_bitset<Block, Allocator>
  1300. operator|(const dynamic_bitset<Block, Allocator>& x,
  1301. const dynamic_bitset<Block, Allocator>& y)
  1302. {
  1303. dynamic_bitset<Block, Allocator> b(x);
  1304. return b |= y;
  1305. }
  1306. template <typename Block, typename Allocator>
  1307. dynamic_bitset<Block, Allocator>
  1308. operator^(const dynamic_bitset<Block, Allocator>& x,
  1309. const dynamic_bitset<Block, Allocator>& y)
  1310. {
  1311. dynamic_bitset<Block, Allocator> b(x);
  1312. return b ^= y;
  1313. }
  1314. template <typename Block, typename Allocator>
  1315. dynamic_bitset<Block, Allocator>
  1316. operator-(const dynamic_bitset<Block, Allocator>& x,
  1317. const dynamic_bitset<Block, Allocator>& y)
  1318. {
  1319. dynamic_bitset<Block, Allocator> b(x);
  1320. return b -= y;
  1321. }
  1322. //-----------------------------------------------------------------------------
  1323. // namespace scope swap
  1324. template<typename Block, typename Allocator>
  1325. inline void
  1326. swap(dynamic_bitset<Block, Allocator>& left,
  1327. dynamic_bitset<Block, Allocator>& right) // no throw
  1328. {
  1329. left.swap(right);
  1330. }
  1331. //-----------------------------------------------------------------------------
  1332. // private (on conforming compilers) member functions
  1333. template <typename Block, typename Allocator>
  1334. inline typename dynamic_bitset<Block, Allocator>::size_type
  1335. dynamic_bitset<Block, Allocator>::calc_num_blocks(size_type num_bits)
  1336. {
  1337. return num_bits / bits_per_block
  1338. + static_cast<int>( num_bits % bits_per_block != 0 );
  1339. }
  1340. // gives a reference to the highest block
  1341. //
  1342. template <typename Block, typename Allocator>
  1343. inline Block& dynamic_bitset<Block, Allocator>::m_highest_block()
  1344. {
  1345. return const_cast<Block &>
  1346. (static_cast<const dynamic_bitset *>(this)->m_highest_block());
  1347. }
  1348. // gives a const-reference to the highest block
  1349. //
  1350. template <typename Block, typename Allocator>
  1351. inline const Block& dynamic_bitset<Block, Allocator>::m_highest_block() const
  1352. {
  1353. assert(size() > 0 && num_blocks() > 0);
  1354. return m_bits.back();
  1355. }
  1356. // If size() is not a multiple of bits_per_block
  1357. // then not all the bits in the last block are used.
  1358. // This function resets the unused bits (convenient
  1359. // for the implementation of many member functions)
  1360. //
  1361. template <typename Block, typename Allocator>
  1362. inline void dynamic_bitset<Block, Allocator>::m_zero_unused_bits()
  1363. {
  1364. assert (num_blocks() == calc_num_blocks(m_num_bits));
  1365. // if != 0 this is the number of bits used in the last block
  1366. const block_width_type extra_bits = count_extra_bits();
  1367. if (extra_bits != 0)
  1368. m_highest_block() &= ~(~static_cast<Block>(0) << extra_bits);
  1369. }
  1370. // check class invariants
  1371. template <typename Block, typename Allocator>
  1372. bool dynamic_bitset<Block, Allocator>::m_check_invariants() const
  1373. {
  1374. const block_width_type extra_bits = count_extra_bits();
  1375. if (extra_bits > 0) {
  1376. block_type const mask = (~static_cast<Block>(0) << extra_bits);
  1377. if ((m_highest_block() & mask) != 0)
  1378. return false;
  1379. }
  1380. if (m_bits.size() > m_bits.capacity() || num_blocks() != calc_num_blocks(size()))
  1381. return false;
  1382. return true;
  1383. }
  1384. } // namespace boost
  1385. #undef BOOST_BITSET_CHAR
  1386. #endif // include guard