2024-03-19 02:34:32 +02:00

295 lines
5.2 KiB
Plaintext

/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <cstddef>
#include <string>
namespace std
{
template <std::size_t N>
class bitset
{
private:
unsigned long long m_bits;
public:
class reference
{
private:
unsigned long long &m_bits;
std::size_t m_pos;
public:
reference(unsigned long long &bits, std::size_t pos) : m_bits(bits), m_pos(pos) {}
~reference() {}
reference &operator=(bool x)
{
if (x)
m_bits |= (1 << m_pos);
else
m_bits &= ~(1 << m_pos);
return *this;
}
reference &operator=(const reference &x)
{
if (x)
m_bits |= (1 << m_pos);
else
m_bits &= ~(1 << m_pos);
return *this;
}
operator bool() const
{
return (m_bits & (1 << m_pos)) != 0;
}
bool operator~() const
{
return (m_bits & (1 << m_pos)) == 0;
}
reference &flip()
{
m_bits ^= (1 << m_pos);
return *this;
}
};
constexpr bitset() : m_bits(0) {}
constexpr bitset(unsigned long long bits) : m_bits(bits) {}
template <class CharT>
explicit bitset(const CharT *str,
std::size_t n = std::size_t(-1),
CharT zero = CharT('0'),
CharT one = CharT('1'))
{
m_bits = 0;
std::size_t len = n == std::size_t(-1) ? std::char_traits<CharT>::length(str) : n;
for (std::size_t i = 0; i < len; i++)
{ /* FIXME: This is a hack, but it works for now. */
if (CharT('0') != zero || CharT('1') != one)
{
if (str[i] == zero)
m_bits &= ~(1ULL << i);
else if (str[i] == one)
m_bits |= (1ULL << i);
}
else
{
if (str[i] == zero)
m_bits |= (0ULL << (N - 1 - i));
else if (str[i] == one)
m_bits |= (1ULL << (N - 1 - i));
}
}
}
bool operator==(const bitset &rhs) const
{
return m_bits == rhs.m_bits;
}
bool operator[](std::size_t pos) const
{
return (m_bits & (1 << pos)) != 0;
}
reference operator[](std::size_t pos)
{
return reference(m_bits, pos);
}
bool test(std::size_t pos) const
{
return (m_bits & (1ULL << pos)) != 0;
}
bool all() const
{
return m_bits == (1ULL << N) - 1;
}
bool any() const
{
return m_bits != 0;
}
bool none() const
{
return m_bits == 0;
}
std::size_t count() const
{
std::size_t count = 0;
for (std::size_t i = 0; i < N; i++)
{
if (test(i))
count++;
}
return count;
}
std::size_t size() const
{
return N;
}
bitset &operator&=(const bitset &other)
{
m_bits &= other.m_bits;
return *this;
}
bitset &operator|=(const bitset &other)
{
m_bits |= other.m_bits;
return *this;
}
bitset &operator^=(const bitset &other)
{
m_bits ^= other.m_bits;
return *this;
}
bitset operator~() const
{
return bitset(~m_bits);
}
bitset operator<<(std::size_t pos) const
{
return bitset(m_bits << pos);
}
bitset &operator<<=(std::size_t pos)
{
m_bits <<= pos;
return *this;
}
bitset operator>>(std::size_t pos) const
{
return bitset(m_bits >> pos);
}
bitset &operator>>=(std::size_t pos)
{
m_bits >>= pos;
return *this;
}
bitset &set()
{
m_bits = (1ULL << N) - 1;
return *this;
}
bitset &set(std::size_t pos, bool value = true)
{
if (value)
m_bits |= (1ULL << pos);
else
m_bits &= ~(1ULL << pos);
return *this;
}
bitset &reset()
{
m_bits = 0;
return *this;
}
bitset &reset(std::size_t pos)
{
m_bits &= ~(1 << pos);
return *this;
}
bitset &flip()
{
m_bits = ~m_bits;
m_bits &= ((1ULL << N) - 1);
return *this;
}
bitset &flip(std::size_t pos)
{
m_bits ^= (1ULL << pos);
m_bits &= ((1ULL << N) - 1);
return *this;
}
std::string to_string(char zero = '0', char one = '1') const
{
std::string str;
for (std::size_t i = N; i > 0; i--)
{
if (test(i - 1))
str += one;
else
str += zero;
}
return str;
}
unsigned long to_ulong() const
{
return static_cast<unsigned long>(m_bits);
}
unsigned long long to_ullong() const
{
return m_bits;
}
};
template <std::size_t N>
std::bitset<N> operator&(const std::bitset<N> &lhs,
const std::bitset<N> &rhs)
{
std::bitset<N> result(lhs);
result &= rhs;
return result;
}
template <std::size_t N>
std::bitset<N> operator|(const std::bitset<N> &lhs,
const std::bitset<N> &rhs)
{
std::bitset<N> result(lhs);
result |= rhs;
return result;
}
template <std::size_t N>
std::bitset<N> operator^(const std::bitset<N> &lhs,
const std::bitset<N> &rhs)
{
std::bitset<N> result(lhs);
result ^= rhs;
return result;
}
}