diff --git a/luna/include/luna/Check.h b/luna/include/luna/Check.h index 4adaca8b..ce3b0472 100644 --- a/luna/include/luna/Check.h +++ b/luna/include/luna/Check.h @@ -14,12 +14,22 @@ if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), message); } \ } while (0) +#define expect_at(expr, location, message) \ + do { \ + if (!(expr)) [[unlikely]] { __check_failed(location, message); } \ + } while (0) + // Like assert(), but always enabled. #define check(expr) \ do { \ if (!(expr)) [[unlikely]] { __check_failed(SourceLocation::current(), #expr); } \ } while (0) +#define check_at(expr, location) \ + do { \ + if (!(expr)) [[unlikely]] { __check_failed(location, #expr); } \ + } while (0) + #define unreachable() __check_failed(SourceLocation::current(), "Reached unreachable code") #define todo() __check_failed(SourceLocation::current(), "Reached a TODO!") diff --git a/luna/include/luna/Option.h b/luna/include/luna/Option.h index 552e72b2..bbe09698 100644 --- a/luna/include/luna/Option.h +++ b/luna/include/luna/Option.h @@ -64,9 +64,9 @@ template class Option return m_has_value; } - T value() const + T value(SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), "Option::value called on an empty Option"); + expect_at(has_value(), caller, "Option::value called on an empty Option"); return m_storage.fetch_reference(); } @@ -75,9 +75,9 @@ template class Option return m_storage.fetch_reference(); } - T release_value() + T release_value(SourceLocation caller = SourceLocation::current()) { - expect(has_value(), "Option::release_value called on an empty Option"); + expect_at(has_value(), caller, "Option::release_value called on an empty Option"); m_has_value = false; return move(m_storage.fetch_reference()); } @@ -129,9 +129,9 @@ template class Option { } - ErrorHandle release_error() + ErrorHandle release_error(SourceLocation caller = SourceLocation::current()) { - expect(!has_value(), "Option::release_error called on a non-empty Option"); + expect_at(!has_value(), caller, "Option::release_error called on a non-empty Option"); return ErrorHandle {}; } diff --git a/luna/include/luna/Result.h b/luna/include/luna/Result.h index b5f128e4..8fd56785 100644 --- a/luna/include/luna/Result.h +++ b/luna/include/luna/Result.h @@ -70,33 +70,33 @@ template class Result return m_value.has_value(); } - int error() const + int error(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::error() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::error() called on a Result that holds a value"); return m_error; } - Error release_error() const + Error release_error(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::release_error() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::release_error() called on a Result that holds a value"); return { m_error }; } - const char* error_string() const + const char* error_string(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::error_string() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::error_string() called on a Result that holds a value"); return ::error_string(m_error); } - T value() const + T value(SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), "Result::value() called on a Result that holds an error"); + expect_at(has_value(), caller, "Result::value() called on a Result that holds an error"); return m_value.unchecked_value({}); } - T expect_value(const char* reason) const + T expect_value(const char* reason, SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), reason); + expect_at(has_value(), caller, reason); return m_value.unchecked_value({}); } @@ -115,15 +115,15 @@ template class Result return m_value.try_move_value(ref); } - T release_value() + T release_value(SourceLocation caller = SourceLocation::current()) { - expect(has_value(), "Result::release_value() called on a Result that holds an error"); + expect_at(has_value(), caller, "Result::release_value() called on a Result that holds an error"); return m_value.unchecked_release_value({}); } - T expect_release_value(const char* reason) + T expect_release_value(const char* reason, SourceLocation caller = SourceLocation::current()) { - expect(has_value(), reason); + expect_at(has_value(), caller, reason); return m_value.unchecked_release_value({}); } @@ -188,45 +188,45 @@ template <> class Result return !m_has_error; } - int error() const + int error(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::error() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::error() called on a Result that holds a value"); return m_error; } - Error release_error() const + Error release_error(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::release_error() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::release_error() called on a Result that holds a value"); return { m_error }; } - const char* error_string() const + const char* error_string(SourceLocation caller = SourceLocation::current()) const { - expect(has_error(), "Result::error_string() called on a Result that holds a value"); + expect_at(has_error(), caller, "Result::error_string() called on a Result that holds a value"); return ::error_string(m_error); } - void value() const + void value(SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), "Result::value() called on a Result that holds an error"); + expect_at(has_value(), caller, "Result::value() called on a Result that holds an error"); return; } - void expect_value(const char* reason) const + void expect_value(const char* reason, SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), reason); + expect_at(has_value(), caller, reason); return; } - void release_value() const + void release_value(SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), "Result::release_value() called on a Result that holds an error"); + expect_at(has_value(), caller, "Result::release_value() called on a Result that holds an error"); return; } - void expect_release_value(const char* reason) const + void expect_release_value(const char* reason, SourceLocation caller = SourceLocation::current()) const { - expect(has_value(), reason); + expect_at(has_value(), caller, reason); return; }