dynamic_bitset.hpp 63 KB

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