LiveKit C++ SDK
Real-time audio/video SDK for C++
Loading...
Searching...
No Matches
result.h
1/*
2 * Copyright 2026 LiveKit
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 LIVEKIT_RESULT_H
18#define LIVEKIT_RESULT_H
19
20#include <cassert>
21#include <optional>
22#include <type_traits>
23#include <utility>
24#include <variant>
25
26namespace livekit {
27
42template <typename T, typename E> class [[nodiscard]] Result {
43public:
45 template <typename U = T,
46 typename = std::enable_if_t<std::is_constructible<T, U &&>::value>>
47 static Result success(U &&value) {
48 return Result(
49 std::variant<T, E>(std::in_place_index<0>, std::forward<U>(value)));
50 }
51
53 template <typename F = E,
54 typename = std::enable_if_t<std::is_constructible<E, F &&>::value>>
55 static Result failure(F &&error) {
56 return Result(
57 std::variant<T, E>(std::in_place_index<1>, std::forward<F>(error)));
58 }
59
61 bool ok() const noexcept { return storage_.index() == 0; }
63 bool has_error() const noexcept { return !ok(); }
65 explicit operator bool() const noexcept { return ok(); }
66
68 T &value() & noexcept {
69 assert(ok());
70 return std::get<0>(storage_);
71 }
72
74 const T &value() const & noexcept {
75 assert(ok());
76 return std::get<0>(storage_);
77 }
78
80 T &&value() && noexcept {
81 assert(ok());
82 return std::get<0>(std::move(storage_));
83 }
84
86 const T &&value() const && noexcept {
87 assert(ok());
88 return std::get<0>(std::move(storage_));
89 }
90
92 E &error() & noexcept {
93 assert(has_error());
94 return std::get<1>(storage_);
95 }
96
98 const E &error() const & noexcept {
99 assert(has_error());
100 return std::get<1>(storage_);
101 }
102
104 E &&error() && noexcept {
105 assert(has_error());
106 return std::get<1>(std::move(storage_));
107 }
108
110 const E &&error() const && noexcept {
111 assert(has_error());
112 return std::get<1>(std::move(storage_));
113 }
114
115private:
116 explicit Result(std::variant<T, E> storage) : storage_(std::move(storage)) {}
117
118 std::variant<T, E> storage_;
119};
120
127template <typename E> class [[nodiscard]] Result<void, E> {
128public:
130 static Result success() { return Result(std::nullopt); }
131
133 template <typename F = E,
134 typename = std::enable_if_t<std::is_constructible<E, F &&>::value>>
135 static Result failure(F &&error) {
136 return Result(std::optional<E>(std::forward<F>(error)));
137 }
138
140 bool ok() const noexcept { return !error_.has_value(); }
142 bool has_error() const noexcept { return error_.has_value(); }
144 explicit operator bool() const noexcept { return ok(); }
145
147 void value() const noexcept { assert(ok()); }
148
150 E &error() & noexcept {
151 assert(has_error());
152 return *error_;
153 }
154
156 const E &error() const & noexcept {
157 assert(has_error());
158 return *error_;
159 }
160
162 E &&error() && noexcept {
163 assert(has_error());
164 return std::move(*error_);
165 }
166
168 const E &&error() const && noexcept {
169 assert(has_error());
170 return std::move(*error_);
171 }
172
173private:
174 explicit Result(std::optional<E> error) : error_(std::move(error)) {}
175
176 std::optional<E> error_;
177};
178
179} // namespace livekit
180
181#endif // LIVEKIT_RESULT_H
E && error() &&noexcept
Move the error value out. Requires has_error() == true.
Definition result.h:162
static Result failure(F &&error)
Construct a failed result containing an error.
Definition result.h:135
bool has_error() const noexcept
True when the operation failed.
Definition result.h:142
bool ok() const noexcept
True when the operation succeeded.
Definition result.h:140
const E & error() const &noexcept
Access the error value. Requires has_error() == true.
Definition result.h:156
const E && error() const &&noexcept
Move the error value out. Requires has_error() == true.
Definition result.h:168
void value() const noexcept
Validates success in debug builds. Mirrors the value() API shape.
Definition result.h:147
static Result success()
Construct a successful result with no payload.
Definition result.h:130
E & error() &noexcept
Access the error value. Requires has_error() == true.
Definition result.h:150
Definition result.h:42
T && value() &&noexcept
Move the success value out. Requires ok() == true.
Definition result.h:80
E & error() &noexcept
Access the error value. Requires has_error() == true.
Definition result.h:92
T & value() &noexcept
Access the success value. Requires ok() == true.
Definition result.h:68
const T && value() const &&noexcept
Move the success value out. Requires ok() == true.
Definition result.h:86
const E && error() const &&noexcept
Move the error value out. Requires has_error() == true.
Definition result.h:110
static Result failure(F &&error)
Construct a failed result containing an error.
Definition result.h:55
static Result success(U &&value)
Construct a successful result containing a value.
Definition result.h:47
bool ok() const noexcept
True when the result contains a success value.
Definition result.h:61
bool has_error() const noexcept
True when the result contains an error.
Definition result.h:63
E && error() &&noexcept
Move the error value out. Requires has_error() == true.
Definition result.h:104
const E & error() const &noexcept
Access the error value. Requires has_error() == true.
Definition result.h:98
const T & value() const &noexcept
Access the success value. Requires ok() == true.
Definition result.h:74