#pragma once #include "bit.h" namespace dark::bits { template concept NonBit = !BitType<_Tp>; template auto cast(_Tp &&val) -> target_size_t { return static_cast(val); } template constexpr auto operator + (_Lhs lhs, _Rhs rhs) { static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len, "operator +: lhs and rhs should have the same length"); return _Lhs { cast(lhs) + cast(rhs) }; } template constexpr auto operator - (_Lhs lhs, _Rhs rhs) { static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len, "operator -: lhs and rhs should have the same length"); return _Lhs { cast(lhs) - cast(rhs) }; } template constexpr auto operator & (_Lhs lhs, _Rhs rhs) { static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len, "operator &: lhs and rhs should have the same length"); return _Lhs { cast(lhs) & cast(rhs) }; } template constexpr auto operator | (_Lhs lhs, _Rhs rhs) { static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len, "operator |: lhs and rhs should have the same length"); return _Lhs { cast(lhs) | cast(rhs) }; } template constexpr auto operator ^ (_Lhs lhs, _Rhs rhs) { static_assert(_Lhs::_Bit_Len == _Rhs::_Bit_Len, "operator ^: lhs and rhs should have the same length"); return _Lhs { cast(lhs) ^ cast(rhs) }; } template constexpr auto operator + (_Lhs lhs, _Rhs rhs) { return _Lhs { cast(lhs) + cast(rhs) }; } template constexpr auto operator - (_Lhs lhs, _Rhs rhs) { return _Lhs { cast(lhs) - cast(rhs) }; } template constexpr auto operator & (_Lhs lhs, _Rhs rhs) { return _Lhs { cast(lhs) & cast(rhs) }; } template constexpr auto operator | (_Lhs lhs, _Rhs rhs) { return _Lhs { cast(lhs) | cast(rhs) }; } template constexpr auto operator ^ (_Lhs lhs, _Rhs rhs) { return _Lhs { cast(lhs) ^ cast(rhs) }; } template constexpr auto operator + (_Lhs lhs, _Rhs rhs) { return _Rhs { cast(lhs) + cast(rhs) }; } template constexpr auto operator - (_Lhs lhs, _Rhs rhs) { return _Rhs { cast(lhs) - cast(rhs) }; } template constexpr auto operator & (_Lhs lhs, _Rhs rhs) { return _Rhs { cast(lhs) & cast(rhs) }; } template constexpr auto operator | (_Lhs lhs, _Rhs rhs) { return _Rhs { cast(lhs) | cast(rhs) }; } template constexpr auto operator ^ (_Lhs lhs, _Rhs rhs) { return _Rhs { cast(lhs) ^ cast(rhs) }; } template constexpr auto operator ~ (_Tp val) { return _Tp { ~cast(val) }; } template constexpr auto operator ! (_Tp val) { return _Tp { !cast(val) }; } } // namespace dark::bits