refactor(bit): change some concept constraints
This commit is contained in:
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
static constexpr std::size_t kMaxLength = std::numeric_limits<max_size_t>::digits;
|
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
template <std::size_t _Nm>
|
||||||
struct Bit {
|
struct Bit {
|
||||||
private:
|
private:
|
||||||
@ -31,10 +29,10 @@ struct Bit {
|
|||||||
requires ((_Tp::_Bit_Len + ...) == _Nm)
|
requires ((_Tp::_Bit_Len + ...) == _Nm)
|
||||||
constexpr Bit(const _Tp &...args);
|
constexpr Bit(const _Tp &...args);
|
||||||
|
|
||||||
template <concepts::bit_match <Bit> _Tp>
|
template <concepts::bit_convertible <_Nm> _Tp>
|
||||||
constexpr Bit &operator=(const _Tp &val);
|
constexpr Bit &operator=(const _Tp &val);
|
||||||
|
|
||||||
template <std::size_t _Hi, std::size_t _Lo = _Hi, concepts::bit_match <Bit> _Tp>
|
template <std::size_t _Hi, std::size_t _Lo = _Hi, concepts::bit_convertible <_Nm> _Tp>
|
||||||
constexpr void set(const _Tp &val);
|
constexpr void set(const _Tp &val);
|
||||||
|
|
||||||
template <std::size_t _Hi, std::size_t _Lo = _Hi>
|
template <std::size_t _Hi, std::size_t _Lo = _Hi>
|
||||||
|
@ -42,7 +42,7 @@ constexpr Bit<_Nm>::Bit(const _Tp &...args)
|
|||||||
: _M_data(int_concat<_Tp::_Bit_Len...>(static_cast<max_size_t>(args)...)) {}
|
: _M_data(int_concat<_Tp::_Bit_Len...>(static_cast<max_size_t>(args)...)) {}
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
template <std::size_t _Nm>
|
||||||
template <concepts::bit_match <Bit <_Nm>> _Tp>
|
template <concepts::bit_convertible <_Nm> _Tp>
|
||||||
constexpr Bit<_Nm> &Bit<_Nm>::operator=(const _Tp &val) {
|
constexpr Bit<_Nm> &Bit<_Nm>::operator=(const _Tp &val) {
|
||||||
this->_M_data = static_cast<max_size_t>(val);
|
this->_M_data = static_cast<max_size_t>(val);
|
||||||
return *this;
|
return *this;
|
||||||
@ -56,17 +56,13 @@ constexpr void Bit<_Nm>::_M_range_check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
template <std::size_t _Nm>
|
||||||
template <std::size_t _Hi, std::size_t _Lo, concepts::bit_match <Bit<_Nm>> _Tp>
|
template <std::size_t _Hi, std::size_t _Lo, concepts::bit_convertible <_Nm> _Tp>
|
||||||
constexpr void Bit<_Nm>::set(const _Tp &val) {
|
constexpr void Bit<_Nm>::set(const _Tp &val) {
|
||||||
this->_M_range_check<_Hi, _Lo>();
|
this->_M_range_check<_Hi, _Lo>();
|
||||||
auto data = static_cast<max_size_t>(val);
|
auto data = static_cast<max_size_t>(val);
|
||||||
constexpr auto _Length = _Hi - _Lo + 1;
|
constexpr auto _Length = _Hi - _Lo + 1;
|
||||||
if constexpr (_Length == kMaxLength) {
|
auto mask = make_mask<_Length> << _Lo;
|
||||||
this->_M_data = data;
|
this->_M_data = (this->_M_data & ~mask) | ((data << _Lo) & mask);
|
||||||
} else {
|
|
||||||
auto mask = ((1 << _Length) - 1) << _Lo;
|
|
||||||
this->_M_data = (this->_M_data & ~mask) | ((data << _Lo) & mask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t _Nm>
|
template <std::size_t _Nm>
|
||||||
@ -82,11 +78,7 @@ template <std::size_t _Len>
|
|||||||
constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit <_Len> {
|
constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit <_Len> {
|
||||||
static_assert(_Len <= _Nm, "Bit::slice: _Len should be no greater than _Nm");
|
static_assert(_Len <= _Nm, "Bit::slice: _Len should be no greater than _Nm");
|
||||||
debug::assert(pos <= _Nm - _Len, "Bit::slice: pos should be less than _Nm - _Len");
|
debug::assert(pos <= _Nm - _Len, "Bit::slice: pos should be less than _Nm - _Len");
|
||||||
if constexpr (_Len == kMaxLength) {
|
return Bit<_Len>(this->_M_data >> pos);
|
||||||
return *this;
|
|
||||||
} else {
|
|
||||||
return Bit<_Len>(this->_M_data >> pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,6 +7,14 @@ namespace dark {
|
|||||||
using max_size_t = std::uint32_t;
|
using max_size_t = std::uint32_t;
|
||||||
using max_ssize_t = std::int32_t;
|
using max_ssize_t = std::int32_t;
|
||||||
|
|
||||||
|
static constexpr std::size_t kMaxLength = std::numeric_limits<max_size_t>::digits;
|
||||||
|
|
||||||
|
template <std::size_t _Len>
|
||||||
|
consteval max_size_t make_mask() {
|
||||||
|
static_assert(_Len <= kMaxLength, "Mask length out of range");
|
||||||
|
return _Len == kMaxLength ? ~max_size_t(0) : (max_size_t(1) << _Len) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dark
|
} // namespace dark
|
||||||
|
|
||||||
namespace dark::concepts {
|
namespace dark::concepts {
|
||||||
@ -38,4 +46,8 @@ concept bit_match =
|
|||||||
(bit_type <_Lhs> && bit_type <_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len)
|
(bit_type <_Lhs> && bit_type <_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len)
|
||||||
|| (int_type <_Lhs> || int_type <_Rhs>);
|
|| (int_type <_Lhs> || int_type <_Rhs>);
|
||||||
|
|
||||||
|
template <typename _Tp, std::size_t _Len>
|
||||||
|
concept bit_convertible =
|
||||||
|
(bit_type <_Tp> && _Tp::_Bit_Len == _Len) || int_type <_Tp>;
|
||||||
|
|
||||||
} // namespace dark::concepts
|
} // namespace dark::concepts
|
||||||
|
Reference in New Issue
Block a user