#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; }; 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