dynamic_bitset.hpp 55 KB

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