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)40inline 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)46inline 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