1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_CMDLINE_CMDLINE_PARSE_RESULT_H_ 18 #define ART_CMDLINE_CMDLINE_PARSE_RESULT_H_ 19 20 #include "cmdline_result.h" 21 #include "detail/cmdline_parser_detail.h" 22 23 namespace art { 24 // Result of a type-parsing attempt. If successful holds the strongly-typed value, 25 // otherwise it holds either a usage or a failure string message that should be displayed back 26 // to the user. 27 // 28 // CmdlineType::Parse/CmdlineType::ParseAndAppend must return this type. 29 template <typename T> 30 struct CmdlineParseResult : CmdlineResult { 31 using CmdlineResult::CmdlineResult; 32 33 // Create an error result with the usage error code and the specified message. UsageCmdlineParseResult34 static CmdlineParseResult Usage(const std::string& message) { 35 return CmdlineParseResult(kUsage, message); 36 } 37 38 // Create an error result with the failure error code and no message. FailureCmdlineParseResult39 static CmdlineParseResult<T> Failure() { 40 return CmdlineParseResult(kFailure); 41 } 42 43 // Create an error result with the failure error code and no message. FailureCmdlineParseResult44 static CmdlineParseResult<T> Failure(const std::string& message) { 45 return CmdlineParseResult(kFailure, message); 46 } 47 48 // Create a successful result which holds the specified value. SuccessCmdlineParseResult49 static CmdlineParseResult<T> Success(const T& value) { 50 return CmdlineParseResult(value); 51 } 52 53 // Create a successful result, taking over the value. SuccessCmdlineParseResult54 static CmdlineParseResult<T> Success(T&& value) { 55 return CmdlineParseResult(std::forward<T>(value)); 56 } 57 58 // Create succesful result, without any values. Used when a value was successfully appended 59 // into an existing object. SuccessNoValueCmdlineParseResult60 static CmdlineParseResult<T> SuccessNoValue() { 61 return CmdlineParseResult(T {}); 62 } 63 64 // Create an error result with the OutOfRange error and the specified message. OutOfRangeCmdlineParseResult65 static CmdlineParseResult<T> OutOfRange(const std::string& message) { 66 return CmdlineParseResult(kOutOfRange, message); 67 } 68 69 // Create an error result with the OutOfRange code and a custom message 70 // which is printed from the actual/min/max values. 71 // Values are converted to string using the ostream<< operator. OutOfRangeCmdlineParseResult72 static CmdlineParseResult<T> OutOfRange(const T& value, 73 const T& min, 74 const T& max) { 75 return CmdlineParseResult(kOutOfRange, 76 "actual: " + art::detail::ToStringAny(value) + 77 ", min: " + art::detail::ToStringAny(min) + 78 ", max: " + art::detail::ToStringAny(max)); 79 } 80 81 // Get a read-only reference to the underlying value. 82 // The result must have been successful and must have a value. GetValueCmdlineParseResult83 const T& GetValue() const { 84 assert(IsSuccess()); 85 assert(has_value_); 86 return value_; 87 } 88 89 // Get a mutable reference to the underlying value. 90 // The result must have been successful and must have a value. GetValueCmdlineParseResult91 T& GetValue() { 92 assert(IsSuccess()); 93 assert(has_value_); 94 return value_; 95 } 96 97 // Take over the value. 98 // The result must have been successful and must have a value. ReleaseValueCmdlineParseResult99 T&& ReleaseValue() { 100 assert(IsSuccess()); 101 assert(has_value_); 102 return std::move(value_); 103 } 104 105 // Whether or not the result has a value (e.g. created with Result::Success). 106 // Error results never have values, success results commonly, but not always, have values. HasValueCmdlineParseResult107 bool HasValue() const { 108 return has_value_; 109 } 110 111 // Cast an error-result from type T2 to T1. 112 // Safe since error-results don't store a typed value. 113 template <typename T2> CastErrorCmdlineParseResult114 static CmdlineParseResult<T> CastError(const CmdlineParseResult<T2>& other) { 115 assert(other.IsError()); 116 return CmdlineParseResult<T>(other.GetStatus()); 117 } 118 119 // Make sure copying is allowed 120 CmdlineParseResult(const CmdlineParseResult&) = default; 121 // Make sure moving is cheap 122 CmdlineParseResult(CmdlineParseResult&&) noexcept = default; 123 124 private: CmdlineParseResultCmdlineParseResult125 explicit CmdlineParseResult(const T& value) 126 : CmdlineResult(kSuccess), value_(value), has_value_(true) {} CmdlineParseResultCmdlineParseResult127 explicit CmdlineParseResult(T&& value) 128 : CmdlineResult(kSuccess), value_(std::forward<T>(value)), has_value_(true) {} CmdlineParseResultCmdlineParseResult129 CmdlineParseResult() 130 : CmdlineResult(kSuccess), value_(), has_value_(false) {} 131 132 T value_; 133 bool has_value_ = false; 134 }; 135 136 } // namespace art 137 138 #endif // ART_CMDLINE_CMDLINE_PARSE_RESULT_H_ 139