|
|
|||
File indexing completed on 2026-05-10 08:44:32
0001 //===- LogicalResult.h - Utilities for handling success/failure -*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLVM_SUPPORT_LOGICALRESULT_H 0010 #define LLVM_SUPPORT_LOGICALRESULT_H 0011 0012 #include <cassert> 0013 #include <optional> 0014 0015 namespace llvm { 0016 /// This class represents an efficient way to signal success or failure. It 0017 /// should be preferred over the use of `bool` when appropriate, as it avoids 0018 /// all of the ambiguity that arises in interpreting a boolean result. This 0019 /// class is marked as NODISCARD to ensure that the result is processed. Users 0020 /// may explicitly discard a result by using `(void)`, e.g. 0021 /// `(void)functionThatReturnsALogicalResult();`. Given the intended nature of 0022 /// this class, it generally shouldn't be used as the result of functions that 0023 /// very frequently have the result ignored. This class is intended to be used 0024 /// in conjunction with the utility functions below. 0025 struct [[nodiscard]] LogicalResult { 0026 public: 0027 /// If isSuccess is true a `success` result is generated, otherwise a 0028 /// 'failure' result is generated. 0029 static LogicalResult success(bool IsSuccess = true) { 0030 return LogicalResult(IsSuccess); 0031 } 0032 0033 /// If isFailure is true a `failure` result is generated, otherwise a 0034 /// 'success' result is generated. 0035 static LogicalResult failure(bool IsFailure = true) { 0036 return LogicalResult(!IsFailure); 0037 } 0038 0039 /// Returns true if the provided LogicalResult corresponds to a success value. 0040 constexpr bool succeeded() const { return IsSuccess; } 0041 0042 /// Returns true if the provided LogicalResult corresponds to a failure value. 0043 constexpr bool failed() const { return !IsSuccess; } 0044 0045 private: 0046 LogicalResult(bool IsSuccess) : IsSuccess(IsSuccess) {} 0047 0048 /// Boolean indicating if this is a success result, if false this is a 0049 /// failure result. 0050 bool IsSuccess; 0051 }; 0052 0053 /// Utility function to generate a LogicalResult. If isSuccess is true a 0054 /// `success` result is generated, otherwise a 'failure' result is generated. 0055 inline LogicalResult success(bool IsSuccess = true) { 0056 return LogicalResult::success(IsSuccess); 0057 } 0058 0059 /// Utility function to generate a LogicalResult. If isFailure is true a 0060 /// `failure` result is generated, otherwise a 'success' result is generated. 0061 inline LogicalResult failure(bool IsFailure = true) { 0062 return LogicalResult::failure(IsFailure); 0063 } 0064 0065 /// Utility function that returns true if the provided LogicalResult corresponds 0066 /// to a success value. 0067 inline bool succeeded(LogicalResult Result) { return Result.succeeded(); } 0068 0069 /// Utility function that returns true if the provided LogicalResult corresponds 0070 /// to a failure value. 0071 inline bool failed(LogicalResult Result) { return Result.failed(); } 0072 0073 /// This class provides support for representing a failure result, or a valid 0074 /// value of type `T`. This allows for integrating with LogicalResult, while 0075 /// also providing a value on the success path. 0076 template <typename T> class [[nodiscard]] FailureOr : public std::optional<T> { 0077 public: 0078 /// Allow constructing from a LogicalResult. The result *must* be a failure. 0079 /// Success results should use a proper instance of type `T`. 0080 FailureOr(LogicalResult Result) { 0081 assert(failed(Result) && 0082 "success should be constructed with an instance of 'T'"); 0083 } 0084 FailureOr() : FailureOr(failure()) {} 0085 FailureOr(T &&Y) : std::optional<T>(std::forward<T>(Y)) {} 0086 FailureOr(const T &Y) : std::optional<T>(Y) {} 0087 template <typename U, 0088 std::enable_if_t<std::is_constructible<T, U>::value> * = nullptr> 0089 FailureOr(const FailureOr<U> &Other) 0090 : std::optional<T>(failed(Other) ? std::optional<T>() 0091 : std::optional<T>(*Other)) {} 0092 0093 operator LogicalResult() const { return success(has_value()); } 0094 0095 private: 0096 /// Hide the bool conversion as it easily creates confusion. 0097 using std::optional<T>::operator bool; 0098 using std::optional<T>::has_value; 0099 }; 0100 0101 /// Wrap a value on the success path in a FailureOr of the same value type. 0102 template <typename T, 0103 typename = std::enable_if_t<!std::is_convertible_v<T, bool>>> 0104 inline auto success(T &&Y) { 0105 return FailureOr<std::decay_t<T>>(std::forward<T>(Y)); 0106 } 0107 0108 /// This class represents success/failure for parsing-like operations that find 0109 /// it important to chain together failable operations with `||`. This is an 0110 /// extended version of `LogicalResult` that allows for explicit conversion to 0111 /// bool. 0112 /// 0113 /// This class should not be used for general error handling cases - we prefer 0114 /// to keep the logic explicit with the `succeeded`/`failed` predicates. 0115 /// However, traditional monadic-style parsing logic can sometimes get 0116 /// swallowed up in boilerplate without this, so we provide this for narrow 0117 /// cases where it is important. 0118 /// 0119 class [[nodiscard]] ParseResult : public LogicalResult { 0120 public: 0121 ParseResult(LogicalResult Result = success()) : LogicalResult(Result) {} 0122 0123 /// Failure is true in a boolean context. 0124 constexpr explicit operator bool() const { return failed(); } 0125 }; 0126 } // namespace llvm 0127 0128 #endif // LLVM_SUPPORT_LOGICALRESULT_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|