123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #ifndef SEMI_BITSET_HPP
- #define SEMI_BITSET_HPP
- #include <cstdint>
- #include <vector>
- #include <bitset>
- using std::size_t;
- static const std::uint64_t lower_half = 0x00000000FFFFFFFF;
- template<size_t size, bool containertype>
- struct semi_bitset{
- using uint64_t = std::uint64_t;
- using uint32_t = std::uint32_t;
- std::vector<uint64_t> data;
- inline semi_bitset() : data(size, 0){}
- inline size_t length()const{
- return size;
- }
- inline semi_bitset<size, containertype> operator<<(int o)const{
- if(o < 0){return this->operator>>(-o);}
- if(o == 0){return *this;}
- semi_bitset<size, containertype> ret;
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i < (size - 1))
- ret.data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
- else
- ret.data[i - jump] = ((data[i] << mod) & lower_half);
- }
- return ret;
- }
- inline semi_bitset<size, containertype> operator>>(int o)const{
- if(o < 0){return this->operator<<(-o);}
- if(o == 0){return *this;}
- semi_bitset<size, containertype> ret;
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i > jump)
- ret.data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
- else
- ret.data[i] = (data[i - jump] >> mod);
- }
- return ret;
- }
- inline semi_bitset<size, containertype>& operator<<=(int o){
- if(o < 0){return this->operator>>=(-o);}
- if(o == 0){return *this;}
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i < (size - 1))
- data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
- else
- data[i - jump] = ((data[i] << mod) & lower_half);
- }
- for(size_t i = size - jump;i < size;i++){
- data[i] = 0;
- }
- return *this;
- }
- inline semi_bitset<size, containertype>& operator>>=(int o){
- if(o < 0){return this->operator<<=(-o);}
- if(o == 0){return *this;}
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = size - 1;i >= jump;i--){
- if(i > jump)
- data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
- else
- data[i] = (data[i - jump] >> mod);
- }
- if(jump > 0)
- for(size_t i = jump - 1;i >= 0;i--){
- data[i] = 0;
- if(i == 0)break;
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype> operator&(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] & o.data[i]);
- }
- return ret;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype> operator^(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] ^ o.data[i]);
- }
- return ret;
-
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype> operator|(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] | o.data[i]);
- }
- return ret;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator&=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data &= o.data[i];
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator^=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data ^= o.data[i];
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator|=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data |= o.data[i];
- }
- return *this;
- }
- template<typename stream, size_t osize,bool ocontainertype>
- inline friend stream& operator<<(stream& s, const semi_bitset<osize, ocontainertype>& o){
- for(size_t i = 0;i < o.data.size();i++)
- s << std::bitset<32>((uint32_t)(o.data[i] & lower_half));
- return s;
- }
- };
- template<std::size_t size>
- struct semi_bitset<size, 0>{
- using uint64_t = std::uint64_t;
- using uint32_t = std::uint32_t;
- uint64_t data[size] = {0};
- static const bool containertype = 0;
- inline semi_bitset<size, containertype> operator<<(int o)const{
- if(o < 0){return this->operator>>(-o);}
- if(o == 0){return *this;}
- semi_bitset<size, containertype> ret;
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i < (size - 1))
- ret.data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
- else
- ret.data[i - jump] = ((data[i] << mod) & lower_half);
- }
- return ret;
- }
- inline size_t length()const{
- return size;
- }
- inline semi_bitset<size, containertype> operator>>(int o)const{
- if(o < 0){return this->operator<<(-o);}
- if(o == 0){return *this;}
- semi_bitset<size, containertype> ret;
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i > jump)
- ret.data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
- else
- ret.data[i] = (data[i - jump] >> mod);
- }
- return ret;
- }
- inline semi_bitset<size, containertype>& operator<<=(int o){
- if(o < 0){return this->operator>>=(-o);}
- if(o == 0){return *this;}
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = jump;i < size;i++){
- if(i < (size - 1))
- data[i - jump] = ((data[i] << mod) & lower_half) | (data[i + 1] >> counter);
- else
- data[i - jump] = ((data[i] << mod) & lower_half);
- }
- for(size_t i = size - jump;i < size;i++){
- data[i] = 0;
- }
- return *this;
- }
- inline semi_bitset<size, containertype>& operator>>=(int o){
- if(o < 0){return this->operator<<=(-o);}
- if(o == 0){return *this;}
- unsigned int jump = o / 32;
- unsigned int mod = o % 32;
- unsigned int counter = 32 - (o % 32);
- for(size_t i = size - 1;i >= jump;i--){
- if(i > jump)
- data[i] = (data[i - jump] >> mod) | ((data[i - jump - 1] << counter) & lower_half);
- else
- data[i] = (data[i - jump] >> mod);
- }
- if(jump > 0)
- for(size_t i = jump - 1;i >= 0;i--){
- data[i] = 0;
- if(i == 0)break;
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype | ocontainertype> operator&(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype | ocontainertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] & o.data[i]);
- }
- return ret;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype | ocontainertype> operator^(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype | ocontainertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] ^ o.data[i]);
- }
- return ret;
-
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype | ocontainertype> operator|(const semi_bitset<osize, ocontainertype>& o)const{
- static_assert(size == osize);
- semi_bitset<size, containertype | ocontainertype> ret;
- for(size_t i = 0;i < size;i++){
- ret.data[i] = (data[i] | o.data[i]);
- }
- return ret;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator&=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data &= o.data[i];
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator^=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data ^= o.data[i];
- }
- return *this;
- }
- template<size_t osize, bool ocontainertype>
- inline semi_bitset<size, containertype>& operator|=(const semi_bitset<osize, ocontainertype>& o){
- static_assert(size == osize);
- for(size_t i = 0;i < size;i++){
- data |= o.data[i];
- }
- return *this;
- }
- /*template<typename stream, size_t osize,bool ocontainertype>
- inline friend stream& operator<<(stream& s, const semi_bitset<osize, ocontainertype>& o){
- for(size_t i = 0;i < osize;i++)
- s << std::bitset<32>((uint32_t)(o.data[i] & lower_half));
- return s;
- }*/
- };
- #endif
|