xdynamic_bitset.hpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /***************************************************************************
  2. * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
  3. * Copyright (c) QuantStack *
  4. * *
  5. * Distributed under the terms of the BSD 3-Clause License. *
  6. * *
  7. * The full license is in the file LICENSE, distributed with this software. *
  8. ****************************************************************************/
  9. #ifndef XDYNAMIC_BITSET_HPP
  10. #define XDYNAMIC_BITSET_HPP
  11. #include <climits>
  12. #include <type_traits>
  13. #include <vector>
  14. #include <initializer_list>
  15. #include <iterator>
  16. #include <memory>
  17. #include <algorithm>
  18. #include "xclosure.hpp"
  19. #include "xspan.hpp"
  20. #include "xiterator_base.hpp"
  21. #include "xtype_traits.hpp"
  22. namespace xtl
  23. {
  24. template <class B, bool is_const>
  25. class xbitset_reference;
  26. template <class B, bool is_const>
  27. class xbitset_iterator;
  28. /******************
  29. * xdyamic_bitset *
  30. ******************/
  31. template <class B>
  32. class xdynamic_bitset_base;
  33. template <class B, class A>
  34. class xdynamic_bitset;
  35. template <class X>
  36. class xdynamic_bitset_view;
  37. template <class X>
  38. struct xdynamic_bitset_traits;
  39. template <class B, class A>
  40. struct xdynamic_bitset_traits<xdynamic_bitset<B, A>>
  41. {
  42. using storage_type = std::vector<B, A>;
  43. using block_type = typename storage_type::value_type;
  44. };
  45. template <class X>
  46. struct xdynamic_bitset_traits<xdynamic_bitset_view<X>>
  47. {
  48. using storage_type = xtl::span<X>;
  49. using block_type = typename storage_type::value_type;
  50. };
  51. template <class X>
  52. struct container_internals;
  53. template <class X>
  54. struct container_internals<xtl::span<X>>
  55. {
  56. using value_type = typename xtl::span<X>::value_type;
  57. static_assert(xtl::is_scalar<value_type>::value, "");
  58. using allocator_type = std::allocator<value_type>;
  59. using size_type = std::size_t;
  60. using difference_type = typename xtl::span<X>::difference_type;
  61. };
  62. template <class X, class A>
  63. struct container_internals<std::vector<X, A>>
  64. {
  65. using value_type = X;
  66. static_assert(xtl::is_scalar<value_type>::value, "");
  67. using allocator_type = A;
  68. using size_type = typename std::vector<X>::size_type;
  69. using difference_type = typename std::vector<X>::difference_type;
  70. };
  71. template <class B>
  72. class xdynamic_bitset_base
  73. {
  74. public:
  75. using self_type = xdynamic_bitset_base<B>;
  76. using derived_class = B;
  77. using storage_type = typename xdynamic_bitset_traits<B>::storage_type;
  78. using block_type = typename xdynamic_bitset_traits<B>::block_type;
  79. using temporary_type = xdynamic_bitset<block_type, std::allocator<block_type>>;
  80. using allocator_type = typename container_internals<storage_type>::allocator_type;
  81. using value_type = bool;
  82. using reference = xbitset_reference<derived_class, false>;
  83. using const_reference = xbitset_reference<derived_class, true>;
  84. using pointer = typename reference::pointer;
  85. using const_pointer = typename const_reference::pointer;
  86. using size_type = typename container_internals<storage_type>::size_type;
  87. using difference_type = typename storage_type::difference_type;
  88. using iterator = xbitset_iterator<derived_class, false>;
  89. using const_iterator = xbitset_iterator<derived_class, true>;
  90. using reverse_iterator = std::reverse_iterator<iterator>;
  91. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  92. using const_block_iterator = typename storage_type::const_iterator;
  93. bool empty() const noexcept;
  94. size_type size() const noexcept;
  95. void swap(self_type& rhs);
  96. reference at(size_type i);
  97. const_reference at(size_type i) const;
  98. reference operator[](size_type i);
  99. const_reference operator[](size_type i) const;
  100. reference front();
  101. const_reference front() const;
  102. reference back();
  103. const_reference back() const;
  104. iterator begin() noexcept;
  105. iterator end() noexcept;
  106. const_iterator begin() const noexcept;
  107. const_iterator end() const noexcept;
  108. const_iterator cbegin() const noexcept;
  109. const_iterator cend() const noexcept;
  110. reverse_iterator rbegin() noexcept;
  111. reverse_iterator rend() noexcept;
  112. const_reverse_iterator rbegin() const noexcept;
  113. const_reverse_iterator rend() const noexcept;
  114. const_reverse_iterator crbegin() const noexcept;
  115. const_reverse_iterator crend() const noexcept;
  116. const_block_iterator block_begin() const noexcept;
  117. const_block_iterator block_end() const noexcept;
  118. template <class R>
  119. self_type& operator&=(const xdynamic_bitset_base<R>& rhs);
  120. template <class R>
  121. self_type& operator|=(const xdynamic_bitset_base<R>& rhs);
  122. template <class R>
  123. self_type& operator^=(const xdynamic_bitset_base<R>& rhs);
  124. temporary_type operator<<(size_type pos);
  125. self_type& operator<<=(size_type pos);
  126. temporary_type operator>>(size_type pos);
  127. self_type& operator>>=(size_type pos);
  128. self_type& set();
  129. self_type& set(size_type pos, value_type value = true);
  130. self_type& reset();
  131. self_type& reset(size_type pos);
  132. self_type& flip();
  133. self_type& flip(size_type pos);
  134. bool all() const noexcept;
  135. bool any() const noexcept;
  136. bool none() const noexcept;
  137. size_type count() const noexcept;
  138. size_type block_count() const noexcept;
  139. block_type* data() noexcept;
  140. const block_type* data() const noexcept;
  141. template <class Y>
  142. bool operator==(const xdynamic_bitset_base<Y>& rhs) const noexcept;
  143. template <class Y>
  144. bool operator!=(const xdynamic_bitset_base<Y>& rhs) const noexcept;
  145. derived_class& derived_cast();
  146. const derived_class& derived_cast() const;
  147. protected:
  148. xdynamic_bitset_base(const storage_type& buffer, std::size_t size);
  149. ~xdynamic_bitset_base() = default;
  150. xdynamic_bitset_base(const xdynamic_bitset_base& rhs) = default;
  151. xdynamic_bitset_base(xdynamic_bitset_base&& rhs) = default;
  152. xdynamic_bitset_base& operator=(const xdynamic_bitset_base& rhs) = default;
  153. xdynamic_bitset_base& operator=(xdynamic_bitset_base&& rhs) = default;
  154. size_type m_size;
  155. storage_type m_buffer;
  156. static constexpr std::size_t s_bits_per_block = CHAR_BIT * sizeof(block_type);
  157. size_type compute_block_count(size_type bits_count) const noexcept;
  158. size_type block_index(size_type pos) const noexcept;
  159. size_type bit_index(size_type pos) const noexcept;
  160. block_type bit_mask(size_type pos) const noexcept;
  161. size_type count_extra_bits() const noexcept;
  162. void zero_unused_bits();
  163. private:
  164. // Make views and buffers friends
  165. template<typename BB>
  166. friend class xdynamic_bitset_base;
  167. };
  168. // NOTE this view ZEROS out remaining bits!
  169. template <class X>
  170. class xdynamic_bitset_view
  171. : public xdynamic_bitset_base<xdynamic_bitset_view<X>>
  172. {
  173. public:
  174. using base_class = xdynamic_bitset_base<xdynamic_bitset_view<X>>;
  175. using storage_type = typename base_class::storage_type;
  176. using block_type = typename base_class::block_type;
  177. xdynamic_bitset_view(block_type* ptr, std::size_t size);
  178. xdynamic_bitset_view() = default;
  179. ~xdynamic_bitset_view() = default;
  180. xdynamic_bitset_view(const xdynamic_bitset_view& rhs) = default;
  181. xdynamic_bitset_view(xdynamic_bitset_view&& rhs) = default;
  182. xdynamic_bitset_view& operator=(const xdynamic_bitset_view& rhs) = default;
  183. xdynamic_bitset_view& operator=(xdynamic_bitset_view&& rhs) = default;
  184. void resize(std::size_t sz);
  185. };
  186. namespace detail_bitset
  187. {
  188. template <class T>
  189. constexpr T integer_ceil(T n, T div)
  190. {
  191. return (n + div - T(1)) / div;
  192. }
  193. }
  194. template <class X>
  195. inline xdynamic_bitset_view<X>::xdynamic_bitset_view(block_type* ptr, std::size_t size)
  196. : base_class(storage_type(ptr, detail_bitset::integer_ceil(size, base_class::s_bits_per_block)), size)
  197. {
  198. base_class::zero_unused_bits();
  199. }
  200. template <class X>
  201. inline void xdynamic_bitset_view<X>::resize(std::size_t sz)
  202. {
  203. if (sz != this->m_size) {
  204. #if defined(XTL_NO_EXCEPTIONS)
  205. std::fprintf(stderr, "cannot resize bitset_view\n");
  206. std::terminate();
  207. #else
  208. throw std::runtime_error("cannot resize bitset_view");
  209. #endif
  210. }
  211. }
  212. template <class B, class A = std::allocator<B>>
  213. class xdynamic_bitset;
  214. template <class B>
  215. auto operator~(const xdynamic_bitset_base<B>& lhs);
  216. template <class L, class R>
  217. auto operator&(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs);
  218. template <class L, class R>
  219. auto operator|(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs);
  220. template <class L, class R>
  221. auto operator^(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs);
  222. template <class B>
  223. void swap(const xdynamic_bitset_base<B>& lhs, const xdynamic_bitset_base<B>& rhs);
  224. /*********************
  225. * xbitset_reference *
  226. *********************/
  227. template <class B, bool is_const>
  228. class xbitset_reference
  229. {
  230. public:
  231. using self_type = xbitset_reference<B, is_const>;
  232. using pointer = std::conditional_t<is_const,
  233. const xclosure_pointer<const self_type>,
  234. xclosure_pointer<self_type>>;
  235. operator bool() const noexcept;
  236. xbitset_reference(const self_type&) = default;
  237. xbitset_reference(self_type&&) = default;
  238. self_type& operator=(const self_type&) noexcept;
  239. self_type& operator=(self_type&&) noexcept;
  240. self_type& operator=(bool) noexcept;
  241. bool operator~() const noexcept;
  242. self_type& operator&=(bool) noexcept;
  243. self_type& operator|=(bool) noexcept;
  244. self_type& operator^=(bool) noexcept;
  245. self_type& flip() noexcept;
  246. pointer operator&() noexcept;
  247. private:
  248. using block_type = typename xdynamic_bitset_traits<B>::block_type;
  249. using closure_type = std::conditional_t<is_const, const block_type&, block_type&>;
  250. xbitset_reference(closure_type block, block_type pos);
  251. void assign(bool) noexcept;
  252. void set() noexcept;
  253. void reset() noexcept;
  254. closure_type m_block;
  255. const block_type m_mask;
  256. template <class BO, bool is_const_other>
  257. friend class xbitset_reference;
  258. friend class xdynamic_bitset_base<B>;
  259. };
  260. /********************
  261. * xbitset_iterator *
  262. ********************/
  263. template <class B, bool is_const>
  264. class xbitset_iterator : public xrandom_access_iterator_base<xbitset_iterator<B, is_const>,
  265. typename xdynamic_bitset_base<B>::value_type,
  266. typename xdynamic_bitset_base<B>::difference_type,
  267. std::conditional_t<is_const,
  268. typename xdynamic_bitset_base<B>::const_pointer,
  269. typename xdynamic_bitset_base<B>::pointer>,
  270. std::conditional_t<is_const,
  271. typename xdynamic_bitset_base<B>::const_reference,
  272. typename xdynamic_bitset_base<B>::reference>>
  273. {
  274. public:
  275. using self_type = xbitset_iterator<B, is_const>;
  276. using container_type = xdynamic_bitset_base<B>;
  277. using value_type = typename container_type::value_type;
  278. using reference = std::conditional_t<is_const,
  279. typename container_type::const_reference,
  280. typename container_type::reference>;
  281. using pointer = std::conditional_t<is_const,
  282. typename container_type::const_pointer,
  283. typename container_type::pointer>;
  284. using size_type = typename container_type::size_type;
  285. using difference_type = typename container_type::difference_type;
  286. using base_type = xrandom_access_iterator_base<self_type, value_type, difference_type, pointer, reference>;
  287. using container_reference = std::conditional_t<is_const, const container_type&, container_type&>;
  288. using container_pointer = std::conditional_t<is_const, const container_type*, container_type*>;
  289. xbitset_iterator() noexcept;
  290. xbitset_iterator(container_reference c, size_type index) noexcept;
  291. self_type& operator++();
  292. self_type& operator--();
  293. self_type& operator+=(difference_type n);
  294. self_type& operator-=(difference_type n);
  295. difference_type operator-(const self_type& rhs) const;
  296. reference operator*() const;
  297. pointer operator->() const;
  298. bool operator==(const self_type& rhs) const;
  299. bool operator<(const self_type& rhs) const;
  300. private:
  301. container_pointer p_container;
  302. size_type m_index;
  303. };
  304. template <class B, class Allocator>
  305. class xdynamic_bitset
  306. : public xdynamic_bitset_base<xdynamic_bitset<B, Allocator>>
  307. {
  308. public:
  309. using allocator_type = Allocator;
  310. using storage_type = std::vector<B, Allocator>;
  311. using base_type = xdynamic_bitset_base<xdynamic_bitset<B, Allocator>>;
  312. using self_type = xdynamic_bitset<B, Allocator>;
  313. using block_type = B;
  314. using reference = typename base_type::reference;
  315. using const_reference = typename base_type::const_reference;
  316. using pointer = typename reference::pointer;
  317. using const_pointer = typename const_reference::pointer;
  318. using size_type = typename storage_type::size_type;
  319. using difference_type = typename storage_type::difference_type;
  320. using iterator = xbitset_iterator<self_type, false>;
  321. using const_iterator = xbitset_iterator<self_type, true>;
  322. using reverse_iterator = std::reverse_iterator<iterator>;
  323. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  324. using base_type::base_type;
  325. using base_type::begin;
  326. using base_type::cbegin;
  327. using base_type::end;
  328. using base_type::cend;
  329. using base_type::rbegin;
  330. using base_type::rend;
  331. using base_type::size;
  332. xdynamic_bitset();
  333. explicit xdynamic_bitset(const allocator_type& allocator);
  334. xdynamic_bitset(size_type count, bool b, const allocator_type& alloc = allocator_type());
  335. explicit xdynamic_bitset(size_type count, const allocator_type& alloc = allocator_type());
  336. xdynamic_bitset(std::initializer_list<bool> init, const allocator_type& alloc = allocator_type());
  337. template <class BlockInputIt>
  338. xdynamic_bitset(BlockInputIt first, BlockInputIt last, const allocator_type& alloc = allocator_type());
  339. xdynamic_bitset(const xdynamic_bitset& rhs);
  340. // Allow creation from views for e.g. temporary creation
  341. template <class Y>
  342. xdynamic_bitset(const xdynamic_bitset_base<Y>& rhs);
  343. ~xdynamic_bitset() = default;
  344. xdynamic_bitset(xdynamic_bitset&& rhs) = default;
  345. xdynamic_bitset& operator=(const xdynamic_bitset& rhs) = default;
  346. xdynamic_bitset& operator=(xdynamic_bitset&& rhs) = default;
  347. void assign(size_type count, bool b);
  348. template <class BlockInputIt>
  349. void assign(BlockInputIt first, BlockInputIt last);
  350. void assign(std::initializer_list<bool> init);
  351. size_type max_size() const noexcept;
  352. void reserve(size_type new_cap);
  353. size_type capacity() const noexcept;
  354. allocator_type get_allocator() const;
  355. void resize(size_type size, bool b = false);
  356. void clear() noexcept;
  357. void push_back(bool b);
  358. void pop_back();
  359. };
  360. /**********************************
  361. * xdynamic_bitset implementation *
  362. **********************************/
  363. template <class B, class A>
  364. inline xdynamic_bitset<B, A>::xdynamic_bitset()
  365. : base_type(storage_type(), size_type(0))
  366. {
  367. }
  368. template <class B, class A>
  369. inline xdynamic_bitset<B, A>::xdynamic_bitset(const allocator_type& allocator)
  370. : base_type(storage_type(allocator), size_type(0))
  371. {
  372. }
  373. template <class B, class A>
  374. inline xdynamic_bitset<B, A>::xdynamic_bitset(size_type count, bool b, const allocator_type& alloc)
  375. : base_type(storage_type(this->compute_block_count(count), b ? ~block_type(0) : block_type(0), alloc), count)
  376. {
  377. this->zero_unused_bits();
  378. }
  379. template <class B, class A>
  380. inline xdynamic_bitset<B, A>::xdynamic_bitset(size_type count, const allocator_type& alloc)
  381. : base_type(storage_type(this->compute_block_count(count), block_type(0), alloc), count)
  382. {
  383. }
  384. template <class B, class A>
  385. template <class BlockInputIt>
  386. inline xdynamic_bitset<B, A>::xdynamic_bitset(BlockInputIt first, BlockInputIt last, const allocator_type& alloc)
  387. : base_type(storage_type(first, last, alloc), size_type(std::distance(first, last)) * base_type::s_bits_per_block)
  388. {
  389. }
  390. template <class B, class A>
  391. inline xdynamic_bitset<B, A>::xdynamic_bitset(std::initializer_list<bool> init, const allocator_type& alloc)
  392. : xdynamic_bitset(init.size(), alloc)
  393. {
  394. std::copy(init.begin(), init.end(), begin());
  395. }
  396. template <class B, class A>
  397. inline xdynamic_bitset<B, A>::xdynamic_bitset(const xdynamic_bitset& rhs)
  398. : base_type(storage_type(rhs.block_begin(), rhs.block_end()), rhs.size())
  399. {
  400. }
  401. template <class B, class A>
  402. template <class Y>
  403. inline xdynamic_bitset<B, A>::xdynamic_bitset(const xdynamic_bitset_base<Y>& rhs)
  404. : base_type(storage_type(rhs.block_begin(), rhs.block_end()), rhs.size())
  405. {
  406. }
  407. template <class B, class A>
  408. inline void xdynamic_bitset<B, A>::assign(size_type count, bool b)
  409. {
  410. resize(count);
  411. b ? this->set() : this->reset();
  412. }
  413. template <class B, class A>
  414. template <class BlockInputIt>
  415. inline void xdynamic_bitset<B, A>::assign(BlockInputIt first, BlockInputIt last)
  416. {
  417. resize(size_type(std::distance(first, last)) * base_type::s_bits_per_block);
  418. std::copy(first, last, this->m_buffer.begin());
  419. }
  420. template <class B, class A>
  421. inline void xdynamic_bitset<B, A>::assign(std::initializer_list<bool> init)
  422. {
  423. resize(init.size());
  424. std::copy(init.begin(), init.end(), begin());
  425. }
  426. template <class B, class A>
  427. inline auto xdynamic_bitset<B, A>::get_allocator() const -> allocator_type
  428. {
  429. return base_type::m_buffer.get_allocator();
  430. }
  431. template <class B>
  432. inline bool xdynamic_bitset_base<B>::empty() const noexcept
  433. {
  434. return m_size == 0;
  435. }
  436. template <class B>
  437. inline auto xdynamic_bitset_base<B>::size() const noexcept -> size_type
  438. {
  439. return m_size;
  440. }
  441. template <class B, class A>
  442. inline auto xdynamic_bitset<B, A>::max_size() const noexcept -> size_type
  443. {
  444. return base_type::m_buffer.max_size() * base_type::s_bits_per_block;
  445. }
  446. template <class B, class A>
  447. inline void xdynamic_bitset<B, A>::reserve(size_type new_cap)
  448. {
  449. base_type::m_buffer.reserve(this->compute_block_count(new_cap));
  450. }
  451. template <class B, class A>
  452. inline auto xdynamic_bitset<B, A>::capacity() const noexcept -> size_type
  453. {
  454. return base_type::m_buffer.capacity() * base_type::s_bits_per_block;
  455. }
  456. template <class B, class A>
  457. inline void xdynamic_bitset<B, A>::resize(size_type asize, bool b)
  458. {
  459. size_type old_block_count = base_type::block_count();
  460. size_type new_block_count = base_type::compute_block_count(asize);
  461. block_type value = b ? ~block_type(0) : block_type(0);
  462. if (new_block_count != old_block_count)
  463. {
  464. base_type::m_buffer.resize(new_block_count, value);
  465. }
  466. if (b && asize > base_type::m_size)
  467. {
  468. size_type extra_bits = base_type::count_extra_bits();
  469. if (extra_bits > 0)
  470. {
  471. base_type::m_buffer[old_block_count - 1] |= (value << extra_bits);
  472. }
  473. }
  474. base_type::m_size = asize;
  475. base_type::zero_unused_bits();
  476. }
  477. template <class B, class A>
  478. inline void xdynamic_bitset<B, A>::clear() noexcept
  479. {
  480. base_type::m_buffer.clear();
  481. base_type::m_size = size_type(0);
  482. }
  483. template <class B, class A>
  484. inline void xdynamic_bitset<B, A>::push_back(bool b)
  485. {
  486. size_type s = size();
  487. resize(s + 1);
  488. this->set(s, b);
  489. }
  490. template <class B, class A>
  491. inline void xdynamic_bitset<B, A>::pop_back()
  492. {
  493. size_type old_block_count = base_type::m_buffer.size();
  494. size_type new_block_count = base_type::compute_block_count(base_type::m_size - 1);
  495. if (new_block_count != old_block_count)
  496. {
  497. base_type::m_buffer.pop_back();
  498. }
  499. --base_type::m_size;
  500. base_type::zero_unused_bits();
  501. }
  502. template <class B>
  503. inline void xdynamic_bitset_base<B>::swap(self_type& rhs)
  504. {
  505. using std::swap;
  506. swap(m_buffer, rhs.m_buffer);
  507. swap(m_size, rhs.m_size);
  508. }
  509. template <class B>
  510. inline auto xdynamic_bitset_base<B>::at(size_type i) -> reference
  511. {
  512. // TODO add real check, remove m_buffer.at ...
  513. return reference(m_buffer.at(block_index(i)), bit_index(i));
  514. }
  515. template <class B>
  516. inline auto xdynamic_bitset_base<B>::at(size_type i) const -> const_reference
  517. {
  518. // TODO add real check, remove m_buffer.at ...
  519. return const_reference(m_buffer.at(block_index(i)), bit_index(i));
  520. }
  521. template <class B>
  522. inline auto xdynamic_bitset_base<B>::operator[](size_type i) -> reference
  523. {
  524. return reference(m_buffer[block_index(i)], bit_index(i));
  525. }
  526. template <class B>
  527. inline auto xdynamic_bitset_base<B>::operator[](size_type i) const -> const_reference
  528. {
  529. return const_reference(m_buffer[block_index(i)], bit_index(i));
  530. }
  531. template <class B>
  532. inline auto xdynamic_bitset_base<B>::front() -> reference
  533. {
  534. return (*this)[0];
  535. }
  536. template <class B>
  537. inline auto xdynamic_bitset_base<B>::front() const -> const_reference
  538. {
  539. return (*this)[0];
  540. }
  541. template <class B>
  542. inline auto xdynamic_bitset_base<B>::back() -> reference
  543. {
  544. return (*this)[m_size - 1];
  545. }
  546. template <class B>
  547. inline auto xdynamic_bitset_base<B>::back() const -> const_reference
  548. {
  549. return (*this)[m_size - 1];
  550. }
  551. template <class B>
  552. inline auto xdynamic_bitset_base<B>::begin() noexcept -> iterator
  553. {
  554. return iterator(*this, size_type(0));
  555. }
  556. template <class B>
  557. inline auto xdynamic_bitset_base<B>::end() noexcept -> iterator
  558. {
  559. return iterator(*this, size());
  560. }
  561. template <class B>
  562. inline auto xdynamic_bitset_base<B>::begin() const noexcept -> const_iterator
  563. {
  564. return cbegin();
  565. }
  566. template <class B>
  567. inline auto xdynamic_bitset_base<B>::end() const noexcept -> const_iterator
  568. {
  569. return cend();
  570. }
  571. template <class B>
  572. inline auto xdynamic_bitset_base<B>::cbegin() const noexcept -> const_iterator
  573. {
  574. return const_iterator(*this, size_type(0));
  575. }
  576. template <class B>
  577. inline auto xdynamic_bitset_base<B>::cend() const noexcept -> const_iterator
  578. {
  579. return const_iterator(*this, size());
  580. }
  581. template <class B>
  582. inline auto xdynamic_bitset_base<B>::rbegin() noexcept -> reverse_iterator
  583. {
  584. return reverse_iterator(end());
  585. }
  586. template <class B>
  587. inline auto xdynamic_bitset_base<B>::rend() noexcept -> reverse_iterator
  588. {
  589. return reverse_iterator(begin());
  590. }
  591. template <class B>
  592. inline auto xdynamic_bitset_base<B>::rbegin() const noexcept -> const_reverse_iterator
  593. {
  594. return crbegin();
  595. }
  596. template <class B>
  597. inline auto xdynamic_bitset_base<B>::rend() const noexcept -> const_reverse_iterator
  598. {
  599. return crend();
  600. }
  601. template <class B>
  602. inline auto xdynamic_bitset_base<B>::crbegin() const noexcept -> const_reverse_iterator
  603. {
  604. return const_reverse_iterator(cend());
  605. }
  606. template <class B>
  607. inline auto xdynamic_bitset_base<B>::crend() const noexcept -> const_reverse_iterator
  608. {
  609. return const_reverse_iterator(cbegin());
  610. }
  611. template <class B>
  612. inline auto xdynamic_bitset_base<B>::block_begin() const noexcept -> const_block_iterator
  613. {
  614. return m_buffer.begin();
  615. }
  616. template <class B>
  617. inline auto xdynamic_bitset_base<B>::block_end() const noexcept -> const_block_iterator
  618. {
  619. return m_buffer.end();
  620. }
  621. template <class B>
  622. template <class R>
  623. inline auto xdynamic_bitset_base<B>::operator&=(const xdynamic_bitset_base<R>& rhs) -> self_type&
  624. {
  625. size_type size = block_count();
  626. for (size_type i = 0; i < size; ++i)
  627. {
  628. m_buffer[i] &= rhs.m_buffer[i];
  629. }
  630. return *this;
  631. }
  632. template <class B>
  633. template <class R>
  634. inline auto xdynamic_bitset_base<B>::operator|=(const xdynamic_bitset_base<R>& rhs) -> self_type&
  635. {
  636. size_type size = block_count();
  637. for (size_type i = 0; i < size; ++i)
  638. {
  639. m_buffer[i] |= rhs.m_buffer[i];
  640. }
  641. return *this;
  642. }
  643. template <class B>
  644. template <class R>
  645. inline auto xdynamic_bitset_base<B>::operator^=(const xdynamic_bitset_base<R>& rhs) -> self_type&
  646. {
  647. size_type size = block_count();
  648. for (size_type i = 0; i < size; ++i)
  649. {
  650. m_buffer[i] ^= rhs.m_buffer[i];
  651. }
  652. return *this;
  653. }
  654. template <class B>
  655. inline auto xdynamic_bitset_base<B>::operator<<(size_type pos) -> temporary_type
  656. {
  657. temporary_type tmp(this->derived_cast());
  658. tmp <<= pos;
  659. return tmp;
  660. }
  661. template <class B>
  662. inline auto xdynamic_bitset_base<B>::operator<<=(size_type pos) -> self_type&
  663. {
  664. if (pos >= m_size)
  665. {
  666. return reset();
  667. }
  668. if (pos > 0)
  669. {
  670. size_type last = block_count() - 1;
  671. size_type div = pos / s_bits_per_block;
  672. size_type r = bit_index(pos);
  673. block_type* b = &m_buffer[0];
  674. if (r != 0)
  675. {
  676. size_type rs = s_bits_per_block - r;
  677. for (size_type i = last - div; i > 0; --i)
  678. {
  679. b[i + div] = (b[i] << r) | (b[i - 1] >> rs);
  680. }
  681. b[div] = b[0] << r;
  682. }
  683. else
  684. {
  685. for (size_type i = last - div; i > 0; --i)
  686. {
  687. b[i + div] = b[i];
  688. }
  689. b[div] = b[0];
  690. }
  691. std::fill_n(m_buffer.begin(), div, block_type(0));
  692. zero_unused_bits();
  693. }
  694. return *this;
  695. }
  696. template <class B>
  697. inline auto xdynamic_bitset_base<B>::operator>>(size_type pos) -> temporary_type
  698. {
  699. temporary_type tmp(this->derived_cast());
  700. tmp >>= pos;
  701. return tmp;
  702. }
  703. template <class B>
  704. inline auto xdynamic_bitset_base<B>::operator>>=(size_type pos) -> self_type&
  705. {
  706. if (pos >= m_size)
  707. {
  708. return reset();
  709. }
  710. if (pos > 0)
  711. {
  712. size_type last = block_count() - 1;
  713. size_type div = pos / s_bits_per_block;
  714. size_type r = bit_index(pos);
  715. block_type* b = &m_buffer[0];
  716. if (r != 0)
  717. {
  718. size_type ls = s_bits_per_block - r;
  719. for (size_type i = div; i < last; ++i)
  720. {
  721. b[i - div] = (b[i] >> r) | (b[i + 1] << ls);
  722. }
  723. b[last - div] = b[last] >> r;
  724. }
  725. else
  726. {
  727. for (size_type i = div; i <= last; ++i)
  728. {
  729. b[i - div] = b[i];
  730. }
  731. }
  732. std::fill_n(m_buffer.begin() + static_cast<std::ptrdiff_t>(block_count() - div), div, block_type(0));
  733. }
  734. return *this;
  735. }
  736. template <class B>
  737. inline auto xdynamic_bitset_base<B>::set() -> self_type&
  738. {
  739. std::fill(m_buffer.begin(), m_buffer.end(), ~block_type(0));
  740. zero_unused_bits();
  741. return *this;
  742. }
  743. template <class B>
  744. inline auto xdynamic_bitset_base<B>::set(size_type pos, value_type value) -> self_type&
  745. {
  746. if (value)
  747. {
  748. m_buffer[block_index(pos)] |= bit_mask(pos);
  749. }
  750. else
  751. {
  752. reset(pos);
  753. }
  754. return *this;
  755. }
  756. template <class B>
  757. inline auto xdynamic_bitset_base<B>::reset() -> self_type&
  758. {
  759. std::fill(m_buffer.begin(), m_buffer.end(), block_type(0));
  760. return *this;
  761. }
  762. template <class B>
  763. inline auto xdynamic_bitset_base<B>::reset(size_type pos) -> self_type&
  764. {
  765. m_buffer[block_index(pos)] &= ~bit_mask(pos);
  766. return *this;
  767. }
  768. template <class B>
  769. inline auto xdynamic_bitset_base<B>::flip() -> self_type&
  770. {
  771. size_type size = block_count();
  772. for (size_type i = 0; i < size; ++i)
  773. {
  774. m_buffer[i] = ~m_buffer[i];
  775. }
  776. zero_unused_bits();
  777. return *this;
  778. }
  779. template <class B>
  780. inline auto xdynamic_bitset_base<B>::flip(size_type pos) -> self_type&
  781. {
  782. m_buffer[block_index(pos)] ^= bit_mask(pos);
  783. return *this;
  784. }
  785. template <class B>
  786. inline bool xdynamic_bitset_base<B>::all() const noexcept
  787. {
  788. if (empty())
  789. return true;
  790. size_type extra_bits = count_extra_bits();
  791. constexpr block_type all_ones = ~block_type(0);
  792. size_type size = extra_bits != 0 ? block_count() - 1 : block_count();
  793. for (size_type i = 0; i < size; ++i)
  794. {
  795. if (m_buffer[i] != all_ones)
  796. return false;
  797. }
  798. if (extra_bits != 0)
  799. {
  800. block_type mask = ~(~block_type(0) << extra_bits);
  801. if (m_buffer.back() != mask)
  802. return false;
  803. }
  804. return true;
  805. }
  806. template <class B>
  807. inline bool xdynamic_bitset_base<B>::any() const noexcept
  808. {
  809. size_type size = block_count();
  810. for (size_type i = 0; i < size; ++i)
  811. {
  812. if (m_buffer[i])
  813. return true;
  814. }
  815. return false;
  816. }
  817. template <class B>
  818. inline bool xdynamic_bitset_base<B>::none() const noexcept
  819. {
  820. return !any();
  821. }
  822. template <class B>
  823. inline auto xdynamic_bitset_base<B>::count() const noexcept -> size_type
  824. {
  825. static constexpr unsigned char table[] =
  826. {
  827. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  828. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  829. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  830. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  831. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  832. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  833. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  834. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
  835. };
  836. size_type res = 0;
  837. const unsigned char* p = static_cast<const unsigned char*>(static_cast<const void*>(&m_buffer[0]));
  838. size_type length = m_buffer.size() * sizeof(block_type);
  839. for (size_type i = 0; i < length; ++i, ++p)
  840. {
  841. res += table[*p];
  842. }
  843. return res;
  844. }
  845. template <class B>
  846. inline auto xdynamic_bitset_base<B>::block_count() const noexcept -> size_type
  847. {
  848. return m_buffer.size();
  849. }
  850. template <class B>
  851. inline auto xdynamic_bitset_base<B>::data() noexcept -> block_type*
  852. {
  853. return m_buffer.data();
  854. }
  855. template <class B>
  856. inline auto xdynamic_bitset_base<B>::data() const noexcept -> const block_type*
  857. {
  858. return m_buffer.data();
  859. }
  860. template <class B>
  861. template <class Y>
  862. inline bool xdynamic_bitset_base<B>::operator==(const xdynamic_bitset_base<Y>& rhs) const noexcept
  863. {
  864. bool is_equal = m_size == rhs.m_size;
  865. if (!is_equal) { return false; }
  866. // we know that block type of lhs & rhs is the same
  867. auto n_blocks = block_count();
  868. for (std::size_t i = 0; i < n_blocks; ++i)
  869. {
  870. if (m_buffer[i] != rhs.m_buffer[i])
  871. {
  872. return false;
  873. }
  874. }
  875. return true;
  876. }
  877. template <class B>
  878. template <class Y>
  879. inline bool xdynamic_bitset_base<B>::operator!=(const xdynamic_bitset_base<Y>& rhs) const noexcept
  880. {
  881. return !(*this == rhs);
  882. }
  883. template <class B>
  884. inline auto xdynamic_bitset_base<B>::derived_cast() -> derived_class&
  885. {
  886. return *(reinterpret_cast<derived_class*>(this));
  887. }
  888. template <class B>
  889. inline auto xdynamic_bitset_base<B>::derived_cast() const -> const derived_class&
  890. {
  891. return *(reinterpret_cast<const derived_class*>(this));
  892. }
  893. template <class B>
  894. inline xdynamic_bitset_base<B>::xdynamic_bitset_base(const storage_type& buffer, std::size_t size)
  895. : m_size(size), m_buffer(buffer)
  896. {
  897. }
  898. template <class B>
  899. inline auto xdynamic_bitset_base<B>::compute_block_count(size_type bits_count) const noexcept -> size_type
  900. {
  901. return bits_count / s_bits_per_block
  902. + static_cast<size_type>(bits_count % s_bits_per_block != 0);
  903. }
  904. template <class B>
  905. inline auto xdynamic_bitset_base<B>::block_index(size_type pos) const noexcept -> size_type
  906. {
  907. return pos / s_bits_per_block;
  908. }
  909. template <class B>
  910. inline auto xdynamic_bitset_base<B>::bit_index(size_type pos) const noexcept -> size_type
  911. {
  912. return pos % s_bits_per_block;
  913. }
  914. template <class B>
  915. inline auto xdynamic_bitset_base<B>::bit_mask(size_type pos) const noexcept -> block_type
  916. {
  917. return block_type(1) << bit_index(pos);
  918. }
  919. template <class B>
  920. inline auto xdynamic_bitset_base<B>::count_extra_bits() const noexcept -> size_type
  921. {
  922. return bit_index(size());
  923. }
  924. template <class B>
  925. inline void xdynamic_bitset_base<B>::zero_unused_bits()
  926. {
  927. size_type extra_bits = count_extra_bits();
  928. if (extra_bits != 0)
  929. {
  930. m_buffer.back() &= ~(~block_type(0) << extra_bits);
  931. }
  932. }
  933. template <class B>
  934. inline auto operator~(const xdynamic_bitset_base<B>& lhs)
  935. {
  936. using temporary_type = typename xdynamic_bitset_base<B>::temporary_type;
  937. temporary_type res(lhs.derived_cast());
  938. res.flip();
  939. return res;
  940. }
  941. template <class L, class R>
  942. inline auto operator&(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs)
  943. {
  944. using temporary_type = typename xdynamic_bitset_base<L>::temporary_type;
  945. temporary_type res(lhs.derived_cast());
  946. res &= rhs;
  947. return res;
  948. }
  949. template <class L, class R>
  950. inline auto operator|(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs)
  951. {
  952. using temporary_type = typename xdynamic_bitset_base<L>::temporary_type;
  953. temporary_type res(lhs.derived_cast());
  954. res |= rhs;
  955. return res;
  956. }
  957. template <class L, class R>
  958. inline auto operator^(const xdynamic_bitset_base<L>& lhs, const xdynamic_bitset_base<R>& rhs)
  959. {
  960. using temporary_type = typename xdynamic_bitset_base<L>::temporary_type;
  961. temporary_type res(lhs.derived_cast());
  962. res ^= rhs;
  963. return res;
  964. }
  965. template <class B>
  966. inline void swap(const xdynamic_bitset_base<B>& lhs, const xdynamic_bitset_base<B>& rhs)
  967. {
  968. return lhs.swap(rhs);
  969. }
  970. /************************************
  971. * xbitset_reference implementation *
  972. ************************************/
  973. template <class B, bool C>
  974. inline xbitset_reference<B, C>::xbitset_reference(closure_type block, block_type pos)
  975. : m_block(block), m_mask(block_type(1) << pos)
  976. {
  977. }
  978. template <class B, bool C>
  979. inline xbitset_reference<B, C>::operator bool() const noexcept
  980. {
  981. return (m_block & m_mask) != 0;
  982. }
  983. template <class B, bool C>
  984. inline auto xbitset_reference<B, C>::operator=(const self_type& rhs) noexcept -> self_type&
  985. {
  986. assign(rhs);
  987. return *this;
  988. }
  989. template <class B, bool C>
  990. inline auto xbitset_reference<B, C>::operator=(self_type&& rhs) noexcept -> self_type&
  991. {
  992. assign(rhs);
  993. return *this;
  994. }
  995. template <class B, bool C>
  996. inline auto xbitset_reference<B, C>::operator=(bool rhs) noexcept -> self_type&
  997. {
  998. assign(rhs);
  999. return *this;
  1000. }
  1001. template <class B, bool C>
  1002. inline bool xbitset_reference<B, C>::operator~() const noexcept
  1003. {
  1004. return (m_block & m_mask) == 0;
  1005. }
  1006. template <class B, bool C>
  1007. inline auto xbitset_reference<B, C>::operator&=(bool rhs) noexcept -> self_type&
  1008. {
  1009. if (!rhs)
  1010. {
  1011. reset();
  1012. }
  1013. return *this;
  1014. }
  1015. template <class B, bool C>
  1016. inline auto xbitset_reference<B, C>::operator|=(bool rhs) noexcept -> self_type&
  1017. {
  1018. if (rhs)
  1019. {
  1020. set();
  1021. }
  1022. return *this;
  1023. }
  1024. template <class B, bool C>
  1025. inline auto xbitset_reference<B, C>::operator^=(bool rhs) noexcept -> self_type&
  1026. {
  1027. return rhs ? flip() : *this;
  1028. }
  1029. template <class B, bool C>
  1030. inline auto xbitset_reference<B, C>::flip() noexcept -> self_type&
  1031. {
  1032. m_block ^= m_mask;
  1033. return *this;
  1034. }
  1035. template <class B, bool C>
  1036. inline auto xbitset_reference<B, C>::operator&() noexcept -> pointer
  1037. {
  1038. return pointer(*this);
  1039. }
  1040. template <class B, bool C>
  1041. inline void xbitset_reference<B, C>::assign(bool rhs) noexcept
  1042. {
  1043. rhs ? set() : reset();
  1044. }
  1045. template <class B, bool C>
  1046. inline void xbitset_reference<B, C>::set() noexcept
  1047. {
  1048. m_block |= m_mask;
  1049. }
  1050. template <class B, bool C>
  1051. inline void xbitset_reference<B, C>::reset() noexcept
  1052. {
  1053. m_block &= ~m_mask;
  1054. }
  1055. /***********************************
  1056. * xbitset_iterator implementation *
  1057. ***********************************/
  1058. template <class B, bool C>
  1059. inline xbitset_iterator<B, C>::xbitset_iterator() noexcept
  1060. : p_container(nullptr), m_index(0)
  1061. {
  1062. }
  1063. template <class B, bool C>
  1064. inline xbitset_iterator<B, C>::xbitset_iterator(container_reference c, size_type index) noexcept
  1065. : p_container(&c), m_index(index)
  1066. {
  1067. }
  1068. template <class B, bool C>
  1069. inline auto xbitset_iterator<B, C>::operator++() -> self_type&
  1070. {
  1071. ++m_index;
  1072. return *this;
  1073. }
  1074. template <class B, bool C>
  1075. inline auto xbitset_iterator<B, C>::operator--() -> self_type&
  1076. {
  1077. --m_index;
  1078. return *this;
  1079. }
  1080. template <class B, bool C>
  1081. inline auto xbitset_iterator<B, C>::operator+=(difference_type n) -> self_type&
  1082. {
  1083. difference_type res = static_cast<difference_type>(m_index) + n;
  1084. m_index = static_cast<size_type>(res);
  1085. return *this;
  1086. }
  1087. template <class B, bool C>
  1088. inline auto xbitset_iterator<B, C>::operator-=(difference_type n) -> self_type&
  1089. {
  1090. difference_type res = static_cast<difference_type>(m_index) - n;
  1091. m_index = static_cast<size_type>(res);
  1092. return *this;
  1093. }
  1094. template <class B, bool C>
  1095. inline auto xbitset_iterator<B, C>::operator-(const self_type& rhs) const -> difference_type
  1096. {
  1097. return difference_type(m_index - rhs.m_index);
  1098. }
  1099. template <class B, bool C>
  1100. inline auto xbitset_iterator<B, C>::operator*() const -> reference
  1101. {
  1102. return (*p_container)[m_index];
  1103. }
  1104. template <class B, bool C>
  1105. inline auto xbitset_iterator<B, C>::operator->() const -> pointer
  1106. {
  1107. return &(operator*());
  1108. }
  1109. template <class B, bool C>
  1110. inline bool xbitset_iterator<B, C>::operator==(const self_type& rhs) const
  1111. {
  1112. return p_container == rhs.p_container && m_index == rhs.m_index;
  1113. }
  1114. template <class B, bool C>
  1115. inline bool xbitset_iterator<B, C>::operator<(const self_type& rhs) const
  1116. {
  1117. return p_container == rhs.p_container && m_index < rhs.m_index;
  1118. }
  1119. }
  1120. #endif