Home | History | Annotate | Download | only in cmdline
      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.
     34   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.
     39   static CmdlineParseResult<T> Failure()  {
     40     return CmdlineParseResult(kFailure);
     41   }
     42 
     43   // Create an error result with the failure error code and no message.
     44   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.
     49   static CmdlineParseResult<T> Success(const T& value) {
     50     return CmdlineParseResult(value);
     51   }
     52 
     53   // Create a successful result, taking over the value.
     54   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.
     60   static CmdlineParseResult<T> SuccessNoValue() {
     61     return CmdlineParseResult(T {});
     62   }
     63 
     64   // Create an error result with the OutOfRange error and the specified message.
     65   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.
     72   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.
     83   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.
     91   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.
     99   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.
    107   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>
    114   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&&) = default;
    123 
    124  private:
    125   explicit CmdlineParseResult(const T& value)
    126     : CmdlineResult(kSuccess), value_(value), has_value_(true) {}
    127   explicit CmdlineParseResult(T&& value)
    128     : CmdlineResult(kSuccess), value_(std::forward<T>(value)), has_value_(true) {}
    129   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