#pragma once #include #include #include namespace dark { using max_size_t = std::uint32_t; using max_ssize_t = std::int32_t; static constexpr std::size_t kMaxLength = std::numeric_limits::digits; template 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::concepts { template using func_t = void (*)(_Tp); template concept implicit_convertible_to = requires(_From &a, func_t<_To> b) { b(a); // Can implicitly convert }; template concept explicit_convertible_to = !implicit_convertible_to<_From, _To> && std::constructible_from<_To, _From>; template concept has_length = requires { { +_Tp::_Bit_Len } -> std::same_as ; }; template concept bit_type = has_length<_Tp> && explicit_convertible_to<_Tp, max_size_t>; template concept int_type = !has_length<_Tp> && implicit_convertible_to<_Tp, max_size_t>; template concept bit_match = (bit_type<_Lhs> && bit_type<_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len) || (int_type<_Lhs> || int_type<_Rhs>); template concept bit_convertible = (bit_type<_Tp> && _Tp::_Bit_Len == _Len) || int_type<_Tp>; } // namespace dark::concepts