// c++23 will give us [[assume]] -- until then we're stuck with various other options: #ifdefined(__clang__) #define SK_ASSUME(cond) __builtin_assume(cond) #elifdefined(__GNUC__) #if __GNUC__ >= 13 #define SK_ASSUME(cond) __attribute__((assume(cond))) #else // NOTE: This implementation could actually evaluate `cond`, which is not desirable. #define SK_ASSUME(cond) ((cond) ? (void)0 : __builtin_unreachable()) #endif #elifdefined(_MSC_VER) #define SK_ASSUME(cond) __assume(cond) #else #define SK_ASSUME(cond) ((void)0) #endif
/** Called internally if we hit an unrecoverable error. The platform implementation must not return, but should either throw an exception or otherwise exit.
*/
[[noreturn]] SK_API externvoid sk_abort_no_print(void);
SK_API externbool sk_abort_is_enabled();
#if !defined(SK_ABORT) # ifdefined(SK_BUILD_FOR_WIN) // This style lets Visual Studio follow errors back to the source file. # define SK_DUMP_LINE_FORMAT "%s(%d)" # else # define SK_DUMP_LINE_FORMAT "%s:%d" # endif # define SK_ABORT(message, ...) \ do { \
SkDebugf(SK_DUMP_LINE_FORMAT ": fatal error: \"" message "\"\n", \
__FILE__, __LINE__, ##__VA_ARGS__); \
SK_DUMP_GOOGLE3_STACK(); \
sk_abort_no_print(); \
} while (false) # define SK_MAYBE_ABORT(message, ...) \ do { if (sk_abort_is_enabled()) { \
SK_ABORT(message, ##__VA_ARGS__); \
} } while(false) #endif
// SkASSERT, SkASSERTF and SkASSERT_RELEASE can be used as standalone assertion expressions, e.g. // uint32_t foo(int x) { // SkASSERT(x > 4); // return x - 4; // } // and are also written to be compatible with constexpr functions: // constexpr uint32_t foo(int x) { // return SkASSERT(x > 4), // x - 4; // } #ifdefined(__clang__) #define SkASSERT_RELEASE(cond) \ static_cast<void>( __builtin_expect(static_cast<bool>(cond), 1) \
? static_cast<void>(0) \
: []{ SK_MAYBE_ABORT("check(%s)", #cond); }() )
// unlike SkASSERT, this macro executes its condition in the non-debug build. // The if is present so that this can be used with functions marked [[nodiscard]]. #define SkAssertResult(cond) if (cond) {} do {} while(false) #endif
#if !defined(SkUNREACHABLE) # ifdefined(_MSC_VER) && !defined(__clang__) # include <intrin.h> # define FAST_FAIL_INVALID_ARG 5 // See https://developercommunity.visualstudio.com/content/problem/1128631/code-flow-doesnt-see-noreturn-with-extern-c.html // for why this is wrapped. Hopefully removable after msvc++ 19.27 is no longer supported.
[[noreturn]] staticinlinevoid sk_fast_fail() { __fastfail(FAST_FAIL_INVALID_ARG); } # define SkUNREACHABLE sk_fast_fail() # else # define SkUNREACHABLE __builtin_trap() # endif #endif
[[noreturn]] SK_API inlinevoid sk_print_index_out_of_bounds(size_t i, size_t size) {
SK_ABORT("Index (%zu) out of bounds for size %zu.\n", i, size);
}
template <typename T> SK_API inline T sk_collection_check_bounds(T i, T size) { if (0 <= i && i < size) SK_LIKELY { return i;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.