1 // Copyright 2022 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <optional> 17 #include <utility> 18 19 #include "pw_assert/assert.h" 20 21 namespace pw::bluetooth { 22 23 // A Result represents the result of an operation which can fail. If it 24 // represents an error, it contains an error value. If it represents success, it 25 // contains zero or one success value. 26 template <typename E, typename... Ts> 27 class Result; 28 29 // Result specialization for returning OK or an error (E). 30 template <typename E> 31 class [[nodiscard]] Result<E> { 32 public: 33 constexpr Result() = default; Result(E error)34 constexpr Result(E error) : error_(error) {} 35 36 constexpr Result(const Result&) = default; 37 constexpr Result& operator=(const Result&) = default; 38 39 constexpr Result(Result&&) = default; 40 constexpr Result& operator=(Result&&) = default; 41 error()42 [[nodiscard]] constexpr E error() const { 43 PW_ASSERT(error_.has_value()); 44 return error_.value(); 45 } ok()46 [[nodiscard]] constexpr bool ok() const { return !error_.has_value(); } 47 48 private: 49 std::optional<E> error_; 50 }; 51 52 // Result specialization for returning some data (T) or an error (E). 53 template <typename E, typename T> 54 class [[nodiscard]] Result<E, T> { 55 public: Result(T && value)56 constexpr Result(T&& value) : value_(std::move(value)) {} Result(const T & value)57 constexpr Result(const T& value) : value_(value) {} 58 59 template <typename... Args> Result(std::in_place_t,Args &&...args)60 constexpr Result(std::in_place_t, Args&&... args) 61 : value_(std::forward<Args>(args)...) {} 62 Result(E error)63 constexpr Result(E error) : error_(error) {} 64 65 constexpr Result(const Result&) = default; 66 constexpr Result& operator=(const Result&) = default; 67 68 constexpr Result(Result&&) = default; 69 constexpr Result& operator=(Result&&) = default; 70 error()71 [[nodiscard]] constexpr E error() const { 72 PW_ASSERT(!value_.has_value()); 73 return error_; 74 } ok()75 [[nodiscard]] constexpr bool ok() const { return value_.has_value(); } 76 value()77 constexpr T& value() & { 78 PW_ASSERT(value_.has_value()); 79 return value_.value(); 80 } 81 value()82 constexpr const T& value() const& { 83 PW_ASSERT(value_.has_value()); 84 return value_.value(); 85 } 86 value()87 constexpr T&& value() && { 88 PW_ASSERT(value_.has_value()); 89 return std::move(value_.value()); 90 } 91 92 private: 93 std::optional<T> value_; 94 // error_ is only initialized if value_ is empty. 95 E error_ = {}; 96 }; 97 98 } // namespace pw::bluetooth 99