22namespace hi {
inline namespace v1 {
30[[nodiscard]]
constexpr bool bound_check(std::unsigned_integral
auto index, std::unsigned_integral
auto upper)
noexcept
32 using value_type = common_integer_t<
decltype(index),
decltype(upper)>;
34 hilet index_ =
static_cast<value_type
>(index);
35 hilet upper_ =
static_cast<value_type
>(upper);
36 return index_ < upper_;
47[[nodiscard]]
constexpr bool bound_check(std::integral
auto index, std::integral
auto lower, std::integral
auto upper)
noexcept
49 using value_type = common_integer_t<
decltype(index),
decltype(lower),
decltype(upper)>;
51 auto index_ =
static_cast<value_type
>(index);
52 auto lower_ =
static_cast<value_type
>(lower);
53 auto upper_ =
static_cast<value_type
>(upper);
56 return index_ >= lower_ and index_ < upper_;
59template<
typename Context>
62 std::ranges::size(range)
63 } -> std::unsigned_integral;
72[[nodiscard]]
constexpr bool bound_check(std::integral
auto index, bound_check_range_helper
auto&& range)
noexcept
74 static_assert(
sizeof(index) <=
sizeof(
size_t));
76 if constexpr (std::is_signed_v<std::decay_t<
decltype(index)>>) {
82 return static_cast<size_t>(index) < std::ranges::size(range);
95#define hi_check(expression, message, ...) \
97 if (not(expression)) { \
98 if constexpr (__VA_OPT__(not ) false) { \
99 throw parse_error(std::format(message __VA_OPT__(, ) __VA_ARGS__)); \
101 throw parse_error(message); \
117#define hi_check_bounds(x, ...) \
119 if (not ::hi::bound_check(x, __VA_ARGS__)) { \
120 throw parse_error("assert bounds: " hi_stringify(x) " between " hi_stringify(__VA_ARGS__)); \
136#define hi_check_subspan(span, offset, ...) \
137 [&](auto _hi_check_subspan_span, size_t _hi_check_subspan_offset, auto... _hi_check_subspan_count) { \
138 if constexpr (sizeof...(_hi_check_subspan_count) == 0) { \
139 if (_hi_check_subspan_offset < _hi_check_subspan_span.size()) { \
140 return _hi_check_subspan_span.subspan(_hi_check_subspan_offset); \
142 } else if constexpr (sizeof...(_hi_check_subspan_count) == 1) { \
143 if (_hi_check_subspan_offset + wide_cast<size_t>(_hi_check_subspan_count...) <= _hi_check_subspan_span.size()) { \
144 return _hi_check_subspan_span.subspan(_hi_check_subspan_offset, _hi_check_subspan_count...); \
148 "assert bounds on: " hi_stringify(span) ".subspan(" hi_stringify(offset __VA_OPT__(", ") __VA_ARGS__) ")"); \
149 }(span, offset __VA_OPT__(, ) __VA_ARGS__)
161#define hi_check_at(span, index) \
162 [&](auto _hi_check_subspan_span, size_t _hi_check_subspan_index) { \
163 if (_hi_check_subspan_index < _hi_check_subspan_span.size()) { \
164 return _hi_check_subspan_span[_hi_check_subspan_index]; \
166 throw parse_error("assert bounds on: " hi_stringify(span) "[" hi_stringify(index) "]"); \
170#define hi_hresult_check(expression) \
171 ([](HRESULT result) { \
172 if (FAILED(result)) { \
173 throw ::hi::io_error(std::format("Call to '{}' failed with {:08x}", #expression, result)); \
184#define hi_assert(expression, ...) \
186 if (not(expression)) { \
187 hi_debug_abort("assert: " __VA_ARGS__ " (" hi_stringify(expression) ")"); \
197#define hi_assert_or_return(x, y) \
199 [[unlikely]] return y; \
210#define hi_assert_bounds(x, ...) \
212 if (not ::hi::bound_check(x, __VA_ARGS__)) { \
213 hi_debug_abort("assert bounds: " hi_stringify(x) " between " hi_stringify(__VA_ARGS__)); \
223#define hi_assert_not_null(x, ...) \
225 if (x == nullptr) { \
226 hi_debug_abort("assert not-null: " __VA_ARGS__ " (" hi_stringify(x) ")"); \
238#define hi_axiom(expression, ...) hi_assert(expression __VA_OPT__(, ) __VA_ARGS__)
249#define hi_axiom_bounds(x, ...) hi_assert_bounds(x, __VA_ARGS__)
257#define hi_axiom_not_null(expression, ...) hi_assert_not_null(expression __VA_OPT__(, ) __VA_ARGS__)
264#define hi_no_default(...) [[unlikely]] hi_debug_abort("Reached no-default:" __VA_ARGS__)
274#define hi_axiom(expression, ...) hi_assume(expression)
285#define hi_axiom_bounds(x, ...) hi_assume(not ::hi::bound_check(x, __VA_ARGS__))
293#define hi_axiom_not_null(expression, ...) hi_assume(expression != nullptr)
300#define hi_no_default(...) hi_unreachable()
308#define hi_static_no_default(...) \
309 []<bool Flag = false>() \
311 static_assert(Flag, "No default: " __VA_ARGS__); \
320#define hi_not_implemented(...) [[unlikely]] hi_debug_abort("Not implemented: " __VA_ARGS__);
327#define hi_static_not_implemented(...) hi_static_no_default("Not implemented: " __VA_ARGS__)
Utilities to interact with the debugger this application runs under.
hi_warning_ignore_msvc(26472)
Definition int_carry.hpp:27
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
Utilities for throwing exceptions and terminating the application.
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
constexpr bool bound_check(std::unsigned_integral auto index, std::unsigned_integral auto upper) noexcept
Check if an unsigned index is less than the bound.
Definition assert.hpp:30