semi_bitset.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #ifndef SEMI_BITSET_HPP
  2. #define SEMI_BITSET_HPP
  3. #include <cstdint>
  4. #include <vector>
  5. #include <bitset>
  6. using std::size_t;
  7. static const std::uint64_t lower_half = 0x00000000FFFFFFFF;
  8. template<size_t size, bool containertype>
  9. struct semi_bitset{
  10. using uint64_t = std::uint64_t;
  11. using uint32_t = std::uint32_t;
  12. std::vector<uint64_t> data;
  13. inline semi_bitset() : data(size, 0){}
  14. inline size_t length()const{
  15. return size;
  16. }
  17. inline semi_bitset<size, containertype> operator<<(int o)const{
  18. if(o < 0){return this->operator>>(-o);}
  19. if(o == 0){return *this;}
  20. semi_bitset<size, containertype> ret;
  21. unsigned int jump = o / 32;
  22. unsigned int mod = o % 32;
  23. unsigned int counter = 32 - (o % 32);
  24. for(size_t i = jump;i < size;i++){
  25. if(i < (size - 1))
  26. ret.data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
  27. else
  28. ret.data[i - jump] = ((data[i] << mod) & lower_half);
  29. }
  30. return ret;
  31. }
  32. inline semi_bitset<size, containertype> operator>>(int o)const{
  33. if(o < 0){return this->operator<<(-o);}
  34. if(o == 0){return *this;}
  35. semi_bitset<size, containertype> ret;
  36. unsigned int jump = o / 32;
  37. unsigned int mod = o % 32;
  38. unsigned int counter = 32 - (o % 32);
  39. for(size_t i = jump;i < size;i++){
  40. if(i > jump)
  41. ret.data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
  42. else
  43. ret.data[i] = (data[i - jump] >> mod);
  44. }
  45. return ret;
  46. }
  47. inline semi_bitset<size, containertype>& operator<<=(int o){
  48. if(o < 0){return this->operator>>=(-o);}
  49. if(o == 0){return *this;}
  50. unsigned int jump = o / 32;
  51. unsigned int mod = o % 32;
  52. unsigned int counter = 32 - (o % 32);
  53. for(size_t i = jump;i < size;i++){
  54. if(i < (size - 1))
  55. data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
  56. else
  57. data[i - jump] = ((data[i] << mod) & lower_half);
  58. }
  59. for(size_t i = size - jump;i < size;i++){
  60. data[i] = 0;
  61. }
  62. return *this;
  63. }
  64. inline semi_bitset<size, containertype>& operator>>=(int o){
  65. if(o < 0){return this->operator<<=(-o);}
  66. if(o == 0){return *this;}
  67. unsigned int jump = o / 32;
  68. unsigned int mod = o % 32;
  69. unsigned int counter = 32 - (o % 32);
  70. for(size_t i = size - 1;i >= jump;i--){
  71. if(i > jump)
  72. data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
  73. else
  74. data[i] = (data[i - jump] >> mod);
  75. }
  76. if(jump > 0)
  77. for(size_t i = jump - 1;i >= 0;i--){
  78. data[i] = 0;
  79. if(i == 0)break;
  80. }
  81. return *this;
  82. }
  83. template<size_t osize, bool ocontainertype>
  84. inline semi_bitset<size, containertype> operator&(const semi_bitset<osize, ocontainertype>& o)const{
  85. static_assert(size == osize);
  86. semi_bitset<size, containertype> ret;
  87. for(size_t i = 0;i < size;i++){
  88. ret.data[i] = (data[i] & o.data[i]);
  89. }
  90. return ret;
  91. }
  92. template<size_t osize, bool ocontainertype>
  93. inline semi_bitset<size, containertype> operator^(const semi_bitset<osize, ocontainertype>& o)const{
  94. static_assert(size == osize);
  95. semi_bitset<size, containertype> ret;
  96. for(size_t i = 0;i < size;i++){
  97. ret.data[i] = (data[i] ^ o.data[i]);
  98. }
  99. return ret;
  100. }
  101. template<size_t osize, bool ocontainertype>
  102. inline semi_bitset<size, containertype> operator|(const semi_bitset<osize, ocontainertype>& o)const{
  103. static_assert(size == osize);
  104. semi_bitset<size, containertype> ret;
  105. for(size_t i = 0;i < size;i++){
  106. ret.data[i] = (data[i] | o.data[i]);
  107. }
  108. return ret;
  109. }
  110. template<size_t osize, bool ocontainertype>
  111. inline semi_bitset<size, containertype>& operator&=(const semi_bitset<osize, ocontainertype>& o){
  112. static_assert(size == osize);
  113. for(size_t i = 0;i < size;i++){
  114. data &= o.data[i];
  115. }
  116. return *this;
  117. }
  118. template<size_t osize, bool ocontainertype>
  119. inline semi_bitset<size, containertype>& operator^=(const semi_bitset<osize, ocontainertype>& o){
  120. static_assert(size == osize);
  121. for(size_t i = 0;i < size;i++){
  122. data ^= o.data[i];
  123. }
  124. return *this;
  125. }
  126. template<size_t osize, bool ocontainertype>
  127. inline semi_bitset<size, containertype>& operator|=(const semi_bitset<osize, ocontainertype>& o){
  128. static_assert(size == osize);
  129. for(size_t i = 0;i < size;i++){
  130. data |= o.data[i];
  131. }
  132. return *this;
  133. }
  134. template<typename stream, size_t osize,bool ocontainertype>
  135. inline friend stream& operator<<(stream& s, const semi_bitset<osize, ocontainertype>& o){
  136. for(size_t i = 0;i < o.data.size();i++)
  137. s << std::bitset<32>((uint32_t)(o.data[i] & lower_half));
  138. return s;
  139. }
  140. };
  141. template<std::size_t size>
  142. struct semi_bitset<size, 0>{
  143. using uint64_t = std::uint64_t;
  144. using uint32_t = std::uint32_t;
  145. uint64_t data[size] = {0};
  146. static const bool containertype = 0;
  147. inline semi_bitset<size, containertype> operator<<(int o)const{
  148. if(o < 0){return this->operator>>(-o);}
  149. if(o == 0){return *this;}
  150. semi_bitset<size, containertype> ret;
  151. unsigned int jump = o / 32;
  152. unsigned int mod = o % 32;
  153. unsigned int counter = 32 - (o % 32);
  154. for(size_t i = jump;i < size;i++){
  155. if(i < (size - 1))
  156. ret.data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
  157. else
  158. ret.data[i - jump] = ((data[i] << mod) & lower_half);
  159. }
  160. return ret;
  161. }
  162. inline size_t length()const{
  163. return size;
  164. }
  165. inline semi_bitset<size, containertype> operator>>(int o)const{
  166. if(o < 0){return this->operator<<(-o);}
  167. if(o == 0){return *this;}
  168. semi_bitset<size, containertype> ret;
  169. unsigned int jump = o / 32;
  170. unsigned int mod = o % 32;
  171. unsigned int counter = 32 - (o % 32);
  172. for(size_t i = jump;i < size;i++){
  173. if(i > jump)
  174. ret.data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
  175. else
  176. ret.data[i] = (data[i - jump] >> mod);
  177. }
  178. return ret;
  179. }
  180. inline semi_bitset<size, containertype>& operator<<=(int o){
  181. if(o < 0){return this->operator>>=(-o);}
  182. if(o == 0){return *this;}
  183. unsigned int jump = o / 32;
  184. unsigned int mod = o % 32;
  185. unsigned int counter = 32 - (o % 32);
  186. for(size_t i = jump;i < size;i++){
  187. if(i < (size - 1))
  188. data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
  189. else
  190. data[i - jump] = ((data[i] << mod) & lower_half);
  191. }
  192. for(size_t i = size - jump;i < size;i++){
  193. data[i] = 0;
  194. }
  195. return *this;
  196. }
  197. inline semi_bitset<size, containertype>& operator>>=(int o){
  198. if(o < 0){return this->operator<<=(-o);}
  199. if(o == 0){return *this;}
  200. unsigned int jump = o / 32;
  201. unsigned int mod = o % 32;
  202. unsigned int counter = 32 - (o % 32);
  203. for(size_t i = size - 1;i >= jump;i--){
  204. if(i > jump)
  205. data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
  206. else
  207. data[i] = (data[i - jump] >> mod);
  208. }
  209. if(jump > 0)
  210. for(size_t i = jump - 1;i >= 0;i--){
  211. data[i] = 0;
  212. if(i == 0)break;
  213. }
  214. return *this;
  215. }
  216. template<size_t osize, bool ocontainertype>
  217. inline semi_bitset<size, containertype | ocontainertype> operator&(const semi_bitset<osize, ocontainertype>& o)const{
  218. static_assert(size == osize);
  219. semi_bitset<size, containertype | ocontainertype> ret;
  220. for(size_t i = 0;i < size;i++){
  221. ret.data[i] = (data[i] & o.data[i]);
  222. }
  223. return ret;
  224. }
  225. template<size_t osize, bool ocontainertype>
  226. inline semi_bitset<size, containertype | ocontainertype> operator^(const semi_bitset<osize, ocontainertype>& o)const{
  227. static_assert(size == osize);
  228. semi_bitset<size, containertype | ocontainertype> ret;
  229. for(size_t i = 0;i < size;i++){
  230. ret.data[i] = (data[i] ^ o.data[i]);
  231. }
  232. return ret;
  233. }
  234. template<size_t osize, bool ocontainertype>
  235. inline semi_bitset<size, containertype | ocontainertype> operator|(const semi_bitset<osize, ocontainertype>& o)const{
  236. static_assert(size == osize);
  237. semi_bitset<size, containertype | ocontainertype> ret;
  238. for(size_t i = 0;i < size;i++){
  239. ret.data[i] = (data[i] | o.data[i]);
  240. }
  241. return ret;
  242. }
  243. template<size_t osize, bool ocontainertype>
  244. inline semi_bitset<size, containertype>& operator&=(const semi_bitset<osize, ocontainertype>& o){
  245. static_assert(size == osize);
  246. for(size_t i = 0;i < size;i++){
  247. data &= o.data[i];
  248. }
  249. return *this;
  250. }
  251. template<size_t osize, bool ocontainertype>
  252. inline semi_bitset<size, containertype>& operator^=(const semi_bitset<osize, ocontainertype>& o){
  253. static_assert(size == osize);
  254. for(size_t i = 0;i < size;i++){
  255. data ^= o.data[i];
  256. }
  257. return *this;
  258. }
  259. template<size_t osize, bool ocontainertype>
  260. inline semi_bitset<size, containertype>& operator|=(const semi_bitset<osize, ocontainertype>& o){
  261. static_assert(size == osize);
  262. for(size_t i = 0;i < size;i++){
  263. data |= o.data[i];
  264. }
  265. return *this;
  266. }
  267. /*template<typename stream, size_t osize,bool ocontainertype>
  268. inline friend stream& operator<<(stream& s, const semi_bitset<osize, ocontainertype>& o){
  269. for(size_t i = 0;i < osize;i++)
  270. s << std::bitset<32>((uint32_t)(o.data[i] & lower_half));
  271. return s;
  272. }*/
  273. };
  274. #endif