1 /* 2 This file is part of solidity. 3 4 solidity is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 solidity is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with solidity. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 // SPDX-License-Identifier: GPL-3.0 18 #pragma once 19 20 #include <string> 21 22 namespace solidity::util 23 { 24 25 /// Simple generic result that holds a value and an optional error message. 26 /// Results can be implicitly converted to and created from the type of 27 /// the value they hold. The class is mainly designed for a result type of 28 /// bool or pointer type. The idea is that the default constructed value of 29 /// the result type is interpreted as an error value. 30 /// 31 /// Result<bool> check() 32 /// { 33 /// if (false) 34 /// return Result<bool>::err("Error message.") 35 /// return true; 36 /// } 37 /// 38 39 template <class ResultType> 40 class [[nodiscard]] Result 41 { 42 public: 43 /// Constructs a result with _value and an empty message. 44 /// This is meant to be called with valid results. Please use 45 /// the static err() member function to signal an error. Result(ResultType _value)46 Result(ResultType _value): Result(_value, std::string{}) {} 47 48 /// Constructs a result with a default-constructed value and an 49 /// error message. err(std::string _message)50 static Result<ResultType> err(std::string _message) 51 { 52 return Result{ResultType{}, std::move(_message)}; 53 } 54 55 /// @{ 56 /// @name Wrapper functions 57 /// Wrapper functions that provide implicit conversions to and explicit retrieval of 58 /// the value this result holds. 59 operator ResultType const&() const { return m_value; } get()60 ResultType const& get() const { return m_value; } 61 /// @} 62 63 /// @returns the error message (can be empty). message()64 std::string const& message() const { return m_message; } 65 66 /// Merges _other into this using the _merger 67 /// and appends the error messages. Meant to be called 68 /// with logical operators like logical_and, etc. 69 template<typename F> merge(Result<ResultType> const & _other,F _merger)70 void merge(Result<ResultType> const& _other, F _merger) 71 { 72 m_value = _merger(m_value, _other.get()); 73 m_message += _other.message(); 74 } 75 76 private: Result(ResultType _value,std::string _message)77 explicit Result(ResultType _value, std::string _message): 78 m_value(std::move(_value)), 79 m_message(std::move(_message)) 80 {} 81 82 ResultType m_value; 83 std::string m_message; 84 }; 85 86 } 87