1 //===- LogicalResult.h - Utilities for handling success/failure -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_SUPPORT_LOGICAL_RESULT_H
10 #define MLIR_SUPPORT_LOGICAL_RESULT_H
11 
12 #include "mlir/Support/LLVM.h"
13 #include "llvm/ADT/Optional.h"
14 
15 namespace mlir {
16 
17 /// Values that can be used to signal success/failure. This should be used in
18 /// conjunction with the utility functions below.
19 struct LogicalResult {
20   enum ResultEnum { Success, Failure } value;
LogicalResultLogicalResult21   LogicalResult(ResultEnum v) : value(v) {}
22 };
23 
24 /// Utility function to generate a LogicalResult. If isSuccess is true a
25 /// `success` result is generated, otherwise a 'failure' result is generated.
26 inline LogicalResult success(bool isSuccess = true) {
27   return LogicalResult{isSuccess ? LogicalResult::Success
28                                  : LogicalResult::Failure};
29 }
30 
31 /// Utility function to generate a LogicalResult. If isFailure is true a
32 /// `failure` result is generated, otherwise a 'success' result is generated.
33 inline LogicalResult failure(bool isFailure = true) {
34   return LogicalResult{isFailure ? LogicalResult::Failure
35                                  : LogicalResult::Success};
36 }
37 
38 /// Utility function that returns true if the provided LogicalResult corresponds
39 /// to a success value.
succeeded(LogicalResult result)40 inline bool succeeded(LogicalResult result) {
41   return result.value == LogicalResult::Success;
42 }
43 
44 /// Utility function that returns true if the provided LogicalResult corresponds
45 /// to a failure value.
failed(LogicalResult result)46 inline bool failed(LogicalResult result) {
47   return result.value == LogicalResult::Failure;
48 }
49 
50 /// This class provides support for representing a failure result, or a valid
51 /// value of type `T`. This allows for integrating with LogicalResult, while
52 /// also providing a value on the success path.
53 template <typename T> class LLVM_NODISCARD FailureOr : public Optional<T> {
54 public:
55   /// Allow constructing from a LogicalResult. The result *must* be a failure.
56   /// Success results should use a proper instance of type `T`.
FailureOr(LogicalResult result)57   FailureOr(LogicalResult result) {
58     assert(failed(result) &&
59            "success should be constructed with an instance of 'T'");
60   }
FailureOr()61   FailureOr() : FailureOr(failure()) {}
FailureOr(T && y)62   FailureOr(T &&y) : Optional<T>(std::forward<T>(y)) {}
63 
LogicalResult()64   operator LogicalResult() const { return success(this->hasValue()); }
65 
66 private:
67   /// Hide the bool conversion as it easily creates confusion.
68   using Optional<T>::operator bool;
69   using Optional<T>::hasValue;
70 };
71 
72 } // namespace mlir
73 
74 #endif // MLIR_SUPPORT_LOGICAL_RESULT_H
75