这在C ++中的Microsoft Visual Studio 2017中。它说语句bigbits<2> ok2 = (ok >> sq) & 1;
不明确。它是如何模棱两可的,我该怎么办?
这是代码。
bigbits.cpp
#include <iostream>
#include "bigbits.h"
int main()
{
bigbits<2> ok = 0x10101010;
int sq = 5;
bigbits<2> ok2 = (ok >> sq) & 1;
system("PAUSE");
return 0;
}
bigbits.h
#ifndef BIGBITS_H_
#define BIGBITS_H_
#include <cinttypes>
#include <utility>
constexpr uint32_t lower_dword(uint64_t n) {
return (uint32_t)(n & UINT32_MAX);
}
constexpr uint32_t upper_dword(uint64_t n) {
return (uint32_t)(n >> 32);
}
template<uint32_t n> class bigbits;
template<>
class bigbits<0U> {};
template<>
class bigbits<1U> {
private:
uint32_t m_head;
constexpr void rshft(uint32_t n) {
m_head >>= n;
}
constexpr void lshft(uint32_t n) {
m_head <<= n;
}
constexpr void b_or(const bigbits& other) {
m_head |= other.m_head;
}
constexpr void b_and(const bigbits& other) {
m_head &= other.m_head;
}
constexpr void b_xor(const bigbits& other) {
m_head ^= other.m_head;
}
constexpr void b_not() {
m_head = ~m_head;
}
constexpr uint32_t rshft_(uint32_t n) {
uint32_t carry = m_head & ((1 << n) - 1);
m_head >>= n;
return carry;
}
constexpr void lshft_(uint32_t n, uint32_t carry) {
m_head <<= n;
m_head |= carry >> (32 - n);
}
constexpr void minus_one_() {
m_head = m_head == 0 ? UINT32_MAX : m_head - 1;
}
public:
constexpr bigbits() : m_head(0) {}
constexpr bigbits(const bigbits& other) : m_head(other.m_head) {}
constexpr bigbits(uint32_t n) : m_head(n) {}
constexpr bigbits(int n) : bigbits((uint32_t)n) {}
constexpr bigbits(uint64_t n) : m_head(lower_dword(n)) {}
constexpr bigbits& operator=(const bigbits& other) {
m_head = other.m_head;
return *this;
}
constexpr bigbits& operator=(uint32_t n) {
m_head = n;
return *this;
}
constexpr bigbits& operator=(int n) {
return operator=((uint32_t)n);
}
constexpr bigbits& operator=(uint64_t n) {
m_head = lower_dword(n);
return *this;
}
constexpr operator uint32_t() const {
return m_head;
}
constexpr operator int() const {
return (int)m_head;
}
constexpr operator uint64_t() const {
return (uint64_t)m_head;
}
constexpr operator bool() const {
return (bool)m_head;
}
constexpr bool operator==(const bigbits& other) const {
return m_head == other.m_head;
}
constexpr bool operator==(uint32_t n) const {
return m_head == n;
}
constexpr bool operator==(int n) const {
return operator==((uint32_t)n);
}
constexpr bool operator!=(const bigbits& other) const {
return m_head != other.m_head;
}
constexpr bool operator!=(uint32_t n) const {
return m_head != n;
}
constexpr bool operator!=(int n) const {
return operator!=((uint32_t)n);
}
constexpr bool operator<(const bigbits& other) const {
return m_head < other.m_head;
}
constexpr bool operator<(uint32_t n) const {
return m_head < n;
}
constexpr bool operator<(int n) const {
return operator<((uint32_t)n);
}
constexpr bool operator>(const bigbits& other) const {
return m_head > other.m_head;
}
constexpr bool operator>(uint32_t n) const {
return m_head > n;
}
constexpr bool operator>(int n) const {
return operator>((uint32_t)n);
}
constexpr bool operator<=(const bigbits& other) const {
return m_head <= other.m_head;
}
constexpr bool operator<=(uint32_t n) const {
return m_head <= n;
}
constexpr bool operator<=(int n) const {
return operator<=((uint32_t)n);
}
constexpr bool operator>=(const bigbits& other) const {
return m_head >= other.m_head;
}
constexpr bool operator>=(uint32_t n) const {
return m_head >= n;
}
constexpr bool operator>=(int n) const {
return operator>=((uint32_t)n);
}
constexpr bigbits& operator>>=(uint32_t n) {
rshft(n);
return *this;
}
constexpr bigbits& operator>>=(int n) {
return *this >>= (uint32_t)n;
}
constexpr bigbits& operator<<=(uint32_t n) {
lshft(n);
return *this;
}
constexpr bigbits& operator<<=(int n) {
return *this <<= (uint32_t)n;
}
constexpr bigbits& operator|=(const bigbits& other) {
b_or(other);
return *this;
}
constexpr bigbits& operator&=(const bigbits& other) {
b_and(other);
return *this;
}
constexpr bigbits& operator^=(const bigbits& other) {
b_xor(other);
return *this;
}
constexpr bigbits operator~() const {
bigbits ret = *this;
ret.b_not();
return ret;
}
constexpr bigbits& minus_one() {
minus_one_();
return *this;
}
friend class bigbits<2>;
};
template<uint32_t n>
class bigbits : protected bigbits<n-1U> {
private:
uint32_t m_head;
typedef bigbits<n - 1U> inherited;
constexpr inherited& tail() { return *this; }
constexpr const inherited& tail() const { return *this; }
constexpr void rshft(uint32_t n) {
while (n > 0) {
uint32_t t = n > 31 ? 31 : n;
rshft_(t);
n -= t;
}
}
constexpr void lshft(uint32_t n) {
while (n > 0) {
uint32_t t = n > 31 ? 31 : n;
lshft_(t, 0);
n -= t;
}
}
constexpr void b_or(const bigbits& other) {
m_head |= other.m_head;
tail().b_or(other.tail());
}
constexpr void b_and(const bigbits& other) {
m_head &= other.m_head;
tail().b_xor(other.tail());
}
constexpr void b_xor(const bigbits& other) {
m_head ^= other.m_head;
tail().b_xor(other.tail());
}
constexpr void b_not() {
m_head = ~m_head;
tail().b_not();
}
constexpr uint32_t rshft_(uint32_t n) {
uint32_t carry = m_head & ((1 << n) - 1);
m_head >>= n;
m_head |= tail().rshft_(n) << (32 - n);
return carry;
}
constexpr void lshft_(uint32_t n, uint32_t carry) {
uint32_t carry2 = m_head & (UINT32_MAX ^ ((1 << (32 - n)) - 1));
m_head <<= n;
m_head |= carry >> (32 - n);
tail().lshft_(n, carry2);
}
//returns a reference
constexpr void minus_one_() {
if (m_head == 0) {
m_head = UINT32_MAX;
tail().minus_one_();
}
else {
m_head -= 1;
}
}
public:
constexpr bigbits() : m_head(0), inherited(0) {}
constexpr bigbits(const bigbits& other) : m_head(other.m_head), inherited(other.tail()) {}
constexpr bigbits(uint32_t n) : m_head(n), inherited(0U) {}
constexpr bigbits(int n) : bigbits((uint32_t)n) {}
constexpr bigbits(uint64_t n) : m_head(lower_dword(n)), inherited(upper_dword(n)) {}
constexpr bigbits& operator=(const bigbits& other) {
m_head = other.m_head;
tail() = other.tail();
return *this;
}
constexpr bigbits& operator=(uint32_t n) {
m_head = n;
tail() = 0U;
return *this;
}
constexpr bigbits& operator=(int n) {
return operator=((uint32_t)n);
}
constexpr bigbits& operator=(uint64_t n) {
m_head = lower_dword(n);
tail() = upper_dword(n);
return *this;
}
constexpr operator uint32_t() const {
return m_head;
}
constexpr operator int() const {
return (int)m_head;
}
constexpr operator uint64_t() const {
return (uint64_t)m_head | ((uint64_t)(uint32_t)tail() << 32);
}
constexpr operator bool() const {
return (bool)m_head || (bool)tail();
}
constexpr bool operator==(const bigbits& other) const {
return (m_head == other.m_head) && (tail() == other.tail());
}
constexpr bool operator==(uint32_t n) const {
return (m_head == n) && (tail() == 0);
}
constexpr bool operator==(int n) const {
return operator==((uint32_t)n);
}
constexpr bool operator!=(const bigbits& other) const {
return (m_head != other.m_head) && (tail() != other.tail());
}
constexpr bool operator!=(uint32_t n) const {
return (m_head != n) && (tail() != 0);
}
constexpr bool operator!=(int n) const {
return operator!=((uint32_t)n);
}
constexpr bool operator<(const bigbits& other) const {
if (tail() < other.tail())
return true;
else if (tail() > other.tail())
return false;
else
return m_head < other.m_head;
}
constexpr bool operator<(uint32_t n) const {
if (tail() > 0) return false;
else return m_head < n;
}
constexpr bool operator<(int n) const {
return operator<((uint32_t)n);
}
constexpr bool operator>(const bigbits& other) const {
if (tail() > other.tail())
return true;
else if (tail() < other.tail())
return false;
else
return m_head > other.m_head;
}
constexpr bool operator>(uint32_t n) const {
if (tail() > 0) return true;
else return m_head < n;
}
constexpr bool operator>(int n) const {
return operator>((uint32_t)n);
}
constexpr bool operator<=(const bigbits& other) const {
if (tail() < other.tail())
return true;
else if (tail() > other.tail())
return false;
else
return m_head <= other.m_head;
}
constexpr bool operator<=(uint32_t n) const {
if (tail() != 0) return false;
else return m_head <= n;
}
constexpr bool operator<=(int n) const {
return operator<=((uint32_t)n);
}
constexpr bool operator>=(const bigbits& other) const {
if (tail() > other.tail())
return true;
else if (tail() < other.tail())
return false;
else
return m_head >= other.m_head;
}
constexpr bool operator>=(uint32_t n) const {
if (tail() != 0) return true;
else return m_head >= n;
}
constexpr bool operator>=(int n) const {
return operator>=((uint32_t)n);
}
constexpr bigbits& operator>>=(uint32_t n) {
rshft(n);
return *this;
}
constexpr bigbits& operator>>=(int n) {
return *this >>= (uint32_t)n;
}
constexpr bigbits& operator<<=(uint32_t n) {
lshft(n);
return *this;
}
constexpr bigbits& operator<<=(int n) {
return *this <<= (uint32_t)n;
}
constexpr bigbits& operator|=(const bigbits& other) {
b_or(other);
return *this;
}
constexpr bigbits& operator&=(const bigbits& other) {
b_and(other);
return *this;
}
constexpr bigbits& operator^=(const bigbits& other) {
b_xor(other);
return *this;
}
constexpr bigbits operator~() const {
bigbits ret = *this;
ret.b_not();
return ret;
}
//returns a reference
constexpr bigbits& minus_one() {
minus_one_();
return *this;
}
friend class bigbits<n + 1U>;
};
template<uint32_t a>
constexpr bigbits<a> operator>>(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret >>= n;
}
template<uint32_t a>
constexpr bigbits<a> operator>>(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret >>= n;
}
template<uint32_t a>
constexpr bigbits<a> operator<<(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret <<= n;
}
template<uint32_t a>
constexpr bigbits<a> operator<<(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret <<= n;
}
template<uint32_t a>
constexpr bigbits<a> operator|(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret |= second;
}
template<uint32_t a>
constexpr bigbits<a> operator&(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret &= second;
}
template<uint32_t a>
constexpr bigbits<a> operator^(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret ^= second;
}
//returns a copy
template<uint32_t a>
constexpr bigbits<a> minus_one(const bigbits<a>& first) {
bigbits<a> ret = first;
return ret.minus_one();
}
template<uint32_t a, class Head>
constexpr void assign_bigbits2_(bigbits<a>& b, Head&& h) {
b |= h;
}
template<uint32_t a, class Head, class...Tail>
constexpr void assign_bigbits2_(bigbits<a>& b, Head&& h, Tail&&...t) {
b |= h;
b <<= 32;
assign_bigbits2_(b, std::forward<Tail>(t)...);
}
template<class...Args>
constexpr bigbits<sizeof...(Args)> assign_bigbits(Args&&...args) {
bigbits<sizeof...(Args)> ret = 0;
assign_bigbits2_(ret, std::forward<Args>(args)...);
return ret;
}
#endif
答案 0 :(得分:0)
好的,所以我已修复它。我添加了 bigbits :: operator&()的更多重载。问题在于它试图将 bigbits 转换为一种基本类型(例如int或bool)。进一步的测试表明,主要问题在于 bigbits :: operator!=()的逻辑。我现在已经解决了。
该项目的目的是能够将开源国际象棋引擎Senpai 1.0(根据GNU通用公共许可证发行)的位板扩展到更大的棋盘。我现在已经成功地使Senpai在其位板上使用 bigbits 而不是 uint64 。在WinBoard中对其进行测试,就引擎的强度,动作的有效性或运行速度而言,似乎没有任何重大的性能下降。这是因为我使用了C ++ 11模板和C ++ 14版本的 constexpr ,它们将大部分计算移至编译时,从而使运行时的计算最少。由于64位整数比32位整数要花费更长的时间(因为后者是大多数现代系统所固有的),因此额外的 bigbits 计算不会对性能产生重大影响。 >
这是更新的bigbits.h代码。对于Senpai未使用的功能,我不能保证100%的功能是正确的,但是可以在Senpai中使用:
/*
Bigbits Copyright (C) 2018 beneficii.
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BIGBITS_H_
#define BIGBITS_H_
#include <cinttypes>
#include <utility>
constexpr uint32_t lower_dword(uint64_t n) {
return (uint32_t)(n & UINT32_MAX);
}
constexpr uint32_t upper_dword(uint64_t n) {
return (uint32_t)(n >> 32);
}
template<uint32_t n> class bigbits;
template<>
class bigbits<0U> {};
template<>
class bigbits<1U> {
private:
uint32_t m_head;
constexpr void rshft(uint32_t n) {
m_head >>= n;
}
constexpr void lshft(uint32_t n) {
m_head <<= n;
}
constexpr void b_or(const bigbits& other) {
m_head |= other.m_head;
}
constexpr void b_and(const bigbits& other) {
m_head &= other.m_head;
}
constexpr void b_xor(const bigbits& other) {
m_head ^= other.m_head;
}
constexpr void b_not() {
m_head = ~m_head;
}
constexpr uint32_t rshft_(uint32_t n) {
uint32_t carry = m_head & ((1 << n) - 1);
m_head >>= n;
return carry;
}
constexpr void lshft_(uint32_t n, uint32_t carry) {
m_head <<= n;
m_head |= carry >> (32 - n);
}
constexpr void minus_one_() {
m_head = m_head == 0 ? UINT32_MAX : m_head - 1;
}
public:
constexpr bigbits() : m_head(0) {}
constexpr bigbits(const bigbits& other) : m_head(other.m_head) {}
constexpr bigbits(uint32_t n) : m_head(n) {}
constexpr bigbits(int n) : bigbits((uint32_t)n) {}
constexpr bigbits(uint64_t n) : m_head(lower_dword(n)) {}
constexpr bigbits& operator=(const bigbits& other) {
m_head = other.m_head;
return *this;
}
constexpr bigbits& operator=(uint32_t n) {
m_head = n;
return *this;
}
constexpr bigbits& operator=(int n) {
return operator=((uint32_t)n);
}
constexpr bigbits& operator=(uint64_t n) {
m_head = lower_dword(n);
return *this;
}
constexpr operator uint32_t() const {
return m_head;
}
constexpr operator int() const {
return (int)m_head;
}
constexpr operator uint64_t() const {
return (uint64_t)m_head;
}
constexpr operator bool() const {
return (bool)m_head;
}
constexpr bool operator==(const bigbits& other) const {
return m_head == other.m_head;
}
constexpr bool operator==(uint32_t n) const {
return m_head == n;
}
constexpr bool operator==(int n) const {
return operator==((uint32_t)n);
}
constexpr bool operator!=(const bigbits& other) const {
return m_head != other.m_head;
}
constexpr bool operator!=(uint32_t n) const {
return m_head != n;
}
constexpr bool operator!=(int n) const {
return operator!=((uint32_t)n);
}
constexpr bool operator<(const bigbits& other) const {
return m_head < other.m_head;
}
constexpr bool operator<(uint32_t n) const {
return m_head < n;
}
constexpr bool operator<(int n) const {
return operator<((uint32_t)n);
}
constexpr bool operator>(const bigbits& other) const {
return m_head > other.m_head;
}
constexpr bool operator>(uint32_t n) const {
return m_head > n;
}
constexpr bool operator>(int n) const {
return operator>((uint32_t)n);
}
constexpr bool operator<=(const bigbits& other) const {
return m_head <= other.m_head;
}
constexpr bool operator<=(uint32_t n) const {
return m_head <= n;
}
constexpr bool operator<=(int n) const {
return operator<=((uint32_t)n);
}
constexpr bool operator>=(const bigbits& other) const {
return m_head >= other.m_head;
}
constexpr bool operator>=(uint32_t n) const {
return m_head >= n;
}
constexpr bool operator>=(int n) const {
return operator>=((uint32_t)n);
}
constexpr bigbits& operator>>=(uint32_t n) {
rshft(n);
return *this;
}
constexpr bigbits& operator>>=(int n) {
return *this >>= (uint32_t)n;
}
constexpr bigbits& operator<<=(uint32_t n) {
lshft(n);
return *this;
}
constexpr bigbits& operator<<=(int n) {
return *this <<= (uint32_t)n;
}
constexpr bigbits& operator|=(const bigbits& other) {
b_or(other);
return *this;
}
constexpr bigbits& operator&=(const bigbits& other) {
b_and(other);
return *this;
}
constexpr bigbits& operator^=(const bigbits& other) {
b_xor(other);
return *this;
}
constexpr bigbits operator~() const {
bigbits ret = *this;
ret.b_not();
return ret;
}
constexpr bigbits& minus_one() {
minus_one_();
return *this;
}
friend class bigbits<2>;
};
template<uint32_t n>
class bigbits : protected bigbits<n-1U> {
private:
uint32_t m_head;
typedef bigbits<n - 1U> inherited;
constexpr inherited& tail() { return *this; }
constexpr const inherited& tail() const { return *this; }
constexpr void rshft(uint32_t n) {
while (n > 0) {
uint32_t t = n > 31 ? 31 : n;
rshft_(t);
n -= t;
}
}
constexpr void lshft(uint32_t n) {
while (n > 0) {
uint32_t t = n > 31 ? 31 : n;
lshft_(t, 0);
n -= t;
}
}
constexpr void b_or(const bigbits& other) {
m_head |= other.m_head;
tail().b_or(other.tail());
}
constexpr void b_and(const bigbits& other) {
m_head &= other.m_head;
tail().b_and(other.tail());
}
constexpr void b_xor(const bigbits& other) {
m_head ^= other.m_head;
tail().b_xor(other.tail());
}
constexpr void b_not() {
m_head = ~m_head;
tail().b_not();
}
constexpr uint32_t rshft_(uint32_t n) {
uint32_t carry = m_head & ((1 << n) - 1);
m_head >>= n;
m_head |= tail().rshft_(n) << (32 - n);
return carry;
}
constexpr void lshft_(uint32_t n, uint32_t carry) {
uint32_t carry2 = m_head & (UINT32_MAX ^ ((1 << (32 - n)) - 1));
m_head <<= n;
m_head |= carry >> (32 - n);
tail().lshft_(n, carry2);
}
//returns a reference
constexpr void minus_one_() {
if (m_head == 0) {
m_head = UINT32_MAX;
tail().minus_one_();
}
else {
m_head -= 1;
}
}
public:
constexpr bigbits() : m_head(0), inherited(0) {}
constexpr bigbits(const bigbits& other) : m_head(other.m_head), inherited(other.tail()) {}
constexpr bigbits(uint32_t n) : m_head(n), inherited(0U) {}
constexpr bigbits(int n) : bigbits((uint32_t)n) {}
constexpr bigbits(uint64_t n) : m_head(lower_dword(n)), inherited(upper_dword(n)) {}
constexpr bigbits& operator=(const bigbits& other) {
m_head = other.m_head;
tail() = other.tail();
return *this;
}
constexpr bigbits& operator=(uint32_t n) {
m_head = n;
tail() = 0U;
return *this;
}
constexpr bigbits& operator=(int n) {
return operator=((uint32_t)n);
}
constexpr bigbits& operator=(uint64_t n) {
m_head = lower_dword(n);
tail() = upper_dword(n);
return *this;
}
constexpr operator uint32_t() const {
return m_head;
}
constexpr operator int() const {
return (int)m_head;
}
constexpr operator uint64_t() const {
return (uint64_t)m_head | ((uint64_t)(uint32_t)tail() << 32);
}
constexpr operator bool() const {
return (bool)m_head || (bool)tail();
}
constexpr bool operator==(const bigbits& other) const {
return (m_head == other.m_head) && (tail() == other.tail());
}
constexpr bool operator==(uint32_t n) const {
return (m_head == n) && (tail() == 0);
}
constexpr bool operator==(int n) const {
return operator==((uint32_t)n);
}
constexpr bool operator!=(const bigbits& other) const {
return !operator==(other);
}
constexpr bool operator!=(uint32_t n) const {
return !operator==(n);
}
constexpr bool operator!=(int n) const {
return operator!=((uint32_t)n);
}
constexpr bool operator<(const bigbits& other) const {
if (tail() < other.tail())
return true;
else if (tail() > other.tail())
return false;
else
return m_head < other.m_head;
}
constexpr bool operator<(uint32_t n) const {
if (tail() > 0) return false;
else return m_head < n;
}
constexpr bool operator<(int n) const {
return operator<((uint32_t)n);
}
constexpr bool operator>(const bigbits& other) const {
if (tail() > other.tail())
return true;
else if (tail() < other.tail())
return false;
else
return m_head > other.m_head;
}
constexpr bool operator>(uint32_t n) const {
if (tail() > 0) return true;
else return m_head < n;
}
constexpr bool operator>(int n) const {
return operator>((uint32_t)n);
}
constexpr bool operator<=(const bigbits& other) const {
if (tail() < other.tail())
return true;
else if (tail() > other.tail())
return false;
else
return m_head <= other.m_head;
}
constexpr bool operator<=(uint32_t n) const {
if (tail() != 0) return false;
else return m_head <= n;
}
constexpr bool operator<=(int n) const {
return operator<=((uint32_t)n);
}
constexpr bool operator>=(const bigbits& other) const {
if (tail() > other.tail())
return true;
else if (tail() < other.tail())
return false;
else
return m_head >= other.m_head;
}
constexpr bool operator>=(uint32_t n) const {
if (tail() != 0) return true;
else return m_head >= n;
}
constexpr bool operator>=(int n) const {
return operator>=((uint32_t)n);
}
constexpr bigbits& operator>>=(uint32_t n) {
rshft(n);
return *this;
}
constexpr bigbits& operator>>=(int n) {
return *this >>= (uint32_t)n;
}
constexpr bigbits& operator<<=(uint32_t n) {
lshft(n);
return *this;
}
constexpr bigbits& operator<<=(int n) {
return *this <<= (uint32_t)n;
}
constexpr bigbits& operator|=(const bigbits& other) {
b_or(other);
return *this;
}
constexpr bigbits& operator&=(const bigbits& other) {
b_and(other);
return *this;
}
constexpr bigbits& operator^=(const bigbits& other) {
b_xor(other);
return *this;
}
constexpr bigbits operator~() const {
bigbits ret = *this;
ret.b_not();
return ret;
}
//returns a reference
constexpr bigbits& minus_one() {
minus_one_();
return *this;
}
friend class bigbits<n + 1U>;
};
template<uint32_t a>
constexpr bigbits<a> operator>>(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret >>= n;
}
template<uint32_t a>
constexpr bigbits<a> operator>>(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret >>= n;
}
template<uint32_t a>
constexpr bigbits<a> operator<<(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret <<= n;
}
template<uint32_t a>
constexpr bigbits<a> operator<<(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret <<= n;
}
template<uint32_t a>
constexpr bigbits<a> operator|(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret |= second;
}
template<uint32_t a>
constexpr bigbits<a> operator|(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret |= n;
}
template<uint32_t a>
constexpr bigbits<a> operator|(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret |= n;
}
template<uint32_t a>
constexpr bigbits<a> operator&(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret &= second;
}
template<uint32_t a>
constexpr bigbits<a> operator&(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret &= n;
}
template<uint32_t a>
constexpr bigbits<a> operator&(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret &= n;
}
template<uint32_t a>
constexpr bigbits<a> operator^(const bigbits<a>& first, const bigbits<a>& second) {
bigbits<a> ret = first;
return ret ^= second;
}
template<uint32_t a>
constexpr bigbits<a> operator^(const bigbits<a>& first, uint32_t n) {
bigbits<a> ret = first;
return ret ^= n;
}
template<uint32_t a>
constexpr bigbits<a> operator^(const bigbits<a>& first, int n) {
bigbits<a> ret = first;
return ret ^= n;
}
//returns a copy
template<uint32_t a>
constexpr bigbits<a> minus_one(const bigbits<a>& first) {
bigbits<a> ret = first;
return ret.minus_one();
}
template<uint32_t a, class Head>
constexpr void assign_bigbits2_(bigbits<a>& b, Head&& h) {
b |= h;
}
template<uint32_t a, class Head, class...Tail>
constexpr void assign_bigbits2_(bigbits<a>& b, Head&& h, Tail&&...t) {
b |= h;
b <<= 32;
assign_bigbits2_(b, std::forward<Tail>(t)...);
}
template<class...Args>
constexpr bigbits<sizeof...(Args)> assign_bigbits(Args&&...args) {
bigbits<sizeof...(Args)> ret = 0;
assign_bigbits2_(ret, std::forward<Args>(args)...);
return ret;
}
#endif
要在Senpai 1.0中使用,请包含 bigbits.h ,将 typedef uint64 bit_t; 替换为 typedef bigbits <2> bit_t; ,并在功能 bit :: rest()中将(b-1)替换为 minus_one(b)。