serenity/AK/Try.h
Andrew Kaster f5d253dcfa Everywhere: Fully qualify IsLvalueReference in TRY() macros
If USING_AK_GLOBALLY is not defined, the name IsLvalueReference might
not be available in the global namespace. Follow the pattern established
in LibTest to fully qualify AK types in macros to avoid this problem.
2023-01-15 00:56:31 +00:00

45 lines
2.7 KiB
C

/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Diagnostics.h>
#include <AK/StdLibExtras.h>
// NOTE: This macro works with any result type that has the expected APIs.
// It's designed with AK::Result and AK::Error in mind.
//
// It depends on a non-standard C++ extension, specifically
// on statement expressions [1]. This is known to be implemented
// by at least clang and gcc.
// [1] https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
//
// If the static_assert below is triggered, it means you tried to return a reference
// from a fallible expression. This will not do what you want; the statement expression
// will create a copy regardless, so it is explicitly disallowed.
#define TRY(expression) \
({ \
/* Ignore -Wshadow to allow nesting the macro. */ \
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
auto _temporary_result = (expression)); \
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \
"Do not return a reference from a fallible expression"); \
if (_temporary_result.is_error()) [[unlikely]] \
return _temporary_result.release_error(); \
_temporary_result.release_value(); \
})
#define MUST(expression) \
({ \
/* Ignore -Wshadow to allow nesting the macro. */ \
AK_IGNORE_DIAGNOSTIC("-Wshadow", \
auto _temporary_result = (expression)); \
static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \
"Do not return a reference from a fallible expression"); \
VERIFY(!_temporary_result.is_error()); \
_temporary_result.release_value(); \
})